一文学习MySQL 意向共享锁、意向排他锁、死锁

一文学习MySQL 意向共享锁、意向排他锁、死锁

基本概念

在MySQL中,锁分为共享锁和排他锁。通过给表或行加锁,可以控制并发访问,保证数据的一致性。但在实际中,使用锁的时候需要考虑多个事务的锁的申请与释放顺序,否则会导致死锁。

MySQL还引入了意向锁的概念。在行级别加锁之前,通过意向锁标记表上接下来需要加的锁类型,以便它能和其他请求的锁协调。在MySQL中,意向锁分为意向共享锁和意向排他锁,它们可以表示事务将要加的锁类型。

意向共享锁和意向排他锁

意向锁标记的是接下来需要加的锁的类型,它并不是真正的锁,而是一种通知。当一段事务想要上锁时,会首先在对象上面请求相应类型的意向锁。

意向锁是一个或多个事务加的锁的通知,以表明它对下一个需要加相应类型的锁有兴趣。因此,在任何时刻只能有唯一一个排他锁,或者同时存在多个共享锁,这些锁都能请求相同的意向锁。

死锁

当发生死锁时,两个或多个事务在等待尚未释放的锁。这些事务不能继续,因此形成了一个循环依赖的状态。这种情况下存在两个或多个事务,每个事务都在等待对方释放锁,而这些事务都不能继续向前推进。

为了避免死锁,应该尽量避免长时间持有锁,尽快释放锁。另外,可以通过规避循环依赖,避免形成死锁。

示例说明

下面通过两个示例来说明意向锁的使用和死锁的产生。

示例一

假设有两个事务T1和T2,T1先进行SELECT操作,请求共享锁并获取,T2接着进行SELECT操作,也请求共享锁,可以发现遵循了意向锁机制。但T1接着进行UPDATE操作,需要改为排他锁,此时会请求意向排他锁,因为此时有意向共享锁存在,所以只能加意向排他锁。T2如果此时也想进行UPDATE操作,会先请求意向排他锁,在检查到意向排他锁存在的情况下,会等待T1事务的排他锁释放。

-- T1
START TRANSACTION;
SELECT * FROM t WHERE id = 1 LOCK IN SHARE MODE;
UPDATE t SET name = 'test' WHERE id = 1;
COMMIT;

-- T2
START TRANSACTION;
SELECT * FROM t WHERE id = 1 LOCK IN SHARE MODE;
-- 排队等待锁

-- T1释放锁后,T2继续执行
UPDATE t SET name = 'test' WHERE id = 1;
COMMIT;

示例二

假设有两个事务T1和T2,在不同的表上进行SELECT和UPDATE操作。在T1事务进行SELECT加共享锁后,T2检查另一个表中没有意向共享锁,于是继续向下执行。但T1事务接着进行UPDATE操作时,需要上排他锁,此时产生了死锁,因为T2事务已经拥有表上行的共享锁,在T1释放行上锁之前,两个事务就会一直等待下去。

-- T1
START TRANSACTION;
SELECT * FROM t1 WHERE id = 1 LOCK IN SHARE MODE;
UPDATE t2 SET name = 'test' WHERE id = 1;
COMMIT;

-- T2
START TRANSACTION;
SELECT * FROM t2 WHERE id = 1 LOCK IN SHARE MODE;
-- 检查到没有意向共享锁
-- 接着向下执行,查询t1
SELECT * FROM t1 WHERE id = 1;
-- 接着上共享锁
SELECT * FROM t1 WHERE id = 2 LOCK IN SHARE MODE;
-- 死锁

在遇到死锁时,MySQL会根据一定的机制自动选择一个事务进行回滚,回到请求的地方重新执行。但一般来说,调整事务的执行顺序还是降低死锁产生的一个可行方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文学习MySQL 意向共享锁、意向排他锁、死锁 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • MySQL抛出Incorrect string value异常分析

    当使用MySQL数据库时,可能会出现“Incorrect string value”的异常。这种错误通常与不兼容字符集有关。本文将提供完整攻略,帮助您解决这个错误。 1. 查看MySQL字符集 首先,我们需要检查MySQL的字符集设置,确保其支持我们要存储的数据。可以通过以下命令查看MySQL字符集: SHOW VARIABLES LIKE ‘%charac…

    database 2023年5月21日
    00
  • Windows下Redis x64的安装与使用教程详解

    Windows下Redis x64的安装与使用教程详解 1. 下载Redis 在Redis官网(https://redis.io/download)下载Redis的Windows版本,选择 .zip 格式的文件,根据自己电脑的架构选择32位或者64位的,下载完成后解压缩到本地磁盘。 2. Redis的安装 进入Redis解压后的文件夹中,找到 redis-s…

    database 2023年5月22日
    00
  • 设置Redis最大占用内存的实现

    设置Redis最大占用内存的实现 Redis是一个开源的内存数据结构存储系统,但是Redis还支持将数据存储到磁盘上的持久化机制。Redis的内存管理对于Redis的性能至关重要,对于Redis的内存管理,我们设置Redis在内存占用超过一定容量时,采取一些预定的行为,如删除键值对,把键值对写入磁盘并清空内存等,来保证Redis的良好运行。 下面是设置Red…

    database 2023年5月22日
    00
  • Windows 下 zip 版的 MySQL 的安装

     创建 配置文件 当 MySQL server 启动时,它会在按照下表列出位置的顺序寻找并读取配置文件: File Name Purpose %PROGRAMDATA%\MySQL\MySQL Server 5.7\my.ini, %PROGRAMDATA%\MySQL\MySQL Server 5.7\my.cnf Global options %WIND…

    MySQL 2023年4月13日
    00
  • MySQL如何为字段添加默认时间浅析

    MySQL为字段添加默认时间的方法是使用DEFAULT关键字和NOW()函数结合。 首先,在创建表时,可以在定义字段时为字段添加DEFAULT关键字和NOW()函数。例如,我们创建一个名为users的表,其中包含一个创建时间字段create_time和一个修改时间字段update_time,它们都有一个默认值为当前时间: CREATE TABLE users…

    database 2023年5月22日
    00
  • MySQL教程DML数据操纵语言示例详解

    MySQL教程DML数据操纵语言示例详解 介绍 本文将详细讲解MySQL的DML数据操纵语言,包含INSERT、UPDATE、DELETE等命令的使用方式以及示例说明。 INSERT命令 INSERT命令用于添加新的数据行到表中。下面是一个简单的示例: INSERT INTO customers(name, email, phone) VALUES(‘Joh…

    database 2023年5月21日
    00
  • MySQL中基本的多表连接查询教程

    MySQL中基本的多表连接查询教程 什么是多表连接查询 MySQL中,多表连接查询是指通过查询多个表的关联关系,将它们联合起来进行查询,以得到更全面的数据结果。在实际中,多表连接查询经常被使用。 多表连接查询的基本语法 多表连接查询的基本语法如下: SELECT column_name(s) FROM table_1 JOIN table_2 ON tabl…

    database 2023年5月22日
    00
  • 主键和外键的区别

    当设计数据库时,主键和外键是两个重要的概念。主键和外键都是用来建立表与表之间联系的,但是二者有着不同的作用。 什么是主键? 主键是一种用于唯一标识一条数据的字段或者字段组。在一个表中,每一条数据的主键值都是唯一的,通过主键可以快速地找到表中的一条记录,还可以通过主键对表中的数据进行操作。 主键有以下几个特点: 主键不能重复,也就是说主键值必须唯一。 非空,主…

    database 2023年3月27日
    00
合作推广
合作推广
分享本页
返回顶部