我之前对死锁的理解一般情况就是A事务锁定了行a,B事务锁定了行b,然后这时A事务请求行b的锁,B事务请求行a的锁,就会HANG住不动,这就产生了死锁。
最近刚刚接触MYSQL,今天在看文档的过程中看到文档中举得一个死锁的例子,如下
下列的例子演示当锁定请求可能会导致死锁之时一个错误会如何发生。例子中包括两个客户端A和B。首先客户端A创建一个包含一个行的表,然后开始一个事务。在这个事务内,A通过在共享模式选择行获得对行的S 锁定:mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;Query OK, 0 rows affected (1.07 sec) mysql> INSERT INTO t (i) VALUES(1);Query OK, 1 row affected (0.09 sec) mysql> START TRANSACTION;Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;+------+| i |+------+| 1 |+------+1 row in set (0.10 sec)接着,客户端B开始一个事务并尝试从该表删除行:mysql> START TRANSACTION;Query OK, 0 rows affected (0.00 sec) mysql> DELETE FROM t WHERE i = 1;删除操作要求一个X 锁定。因为这个锁定不兼容客户端A持有的S锁定,所以X 锁定不被允许,所以请求进入对行及客户端阻挡的锁定请求队列。最后,客户端A也试图从表中删除该行:mysql> DELETE FROM t WHERE i = 1;ERROR 1213 (40001): Deadlock found when trying to get lock;try restarting transaction客户端A首先对i=1那一行获取了S锁,然后客户端B在delete的时候尝试获取X锁就会进入等待,直到这一步我还是能理解的。可是后来在客户端A尝试删除i=1的数据行的时候,却报发生了死锁的错误,这是为什么呢?
最近刚刚接触MYSQL,今天在看文档的过程中看到文档中举得一个死锁的例子,如下
下列的例子演示当锁定请求可能会导致死锁之时一个错误会如何发生。例子中包括两个客户端A和B。首先客户端A创建一个包含一个行的表,然后开始一个事务。在这个事务内,A通过在共享模式选择行获得对行的S 锁定:mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;Query OK, 0 rows affected (1.07 sec) mysql> INSERT INTO t (i) VALUES(1);Query OK, 1 row affected (0.09 sec) mysql> START TRANSACTION;Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;+------+| i |+------+| 1 |+------+1 row in set (0.10 sec)接着,客户端B开始一个事务并尝试从该表删除行:mysql> START TRANSACTION;Query OK, 0 rows affected (0.00 sec) mysql> DELETE FROM t WHERE i = 1;删除操作要求一个X 锁定。因为这个锁定不兼容客户端A持有的S锁定,所以X 锁定不被允许,所以请求进入对行及客户端阻挡的锁定请求队列。最后,客户端A也试图从表中删除该行:mysql> DELETE FROM t WHERE i = 1;ERROR 1213 (40001): Deadlock found when trying to get lock;try restarting transaction客户端A首先对i=1那一行获取了S锁,然后客户端B在delete的时候尝试获取X锁就会进入等待,直到这一步我还是能理解的。可是后来在客户端A尝试删除i=1的数据行的时候,却报发生了死锁的错误,这是为什么呢?
解决方案 »
- QT跟数据库的连接问题
- 有关mysql存储过程的小问题
- MySql重复插入的问题
- MySQL数据库中的数据哪去了?
- 我发现了Mysql的一个BUG大家注意
- 执行查询语句时cpu使用问题
- 请问怎样使用mysql administrator中的自动备份功能啊?
- 请问在MySQL里,怎么取得 自动ID号为最大 的一笔记录?
- create table 字段default值的问题
- oracle转 mysql view的问题
- 请教关于MYSQL中order by的效率优化
- Mysql 时间段查询:相同gaddress的,当前时间 大于 gstarttime ,且小于gstoptime ,排列的第一条数据。
当事务中包含select ...lock in share mode的时候,相关记录将会被锁住,不允许进行修改。这个语句限制在事务表的其他连接上进行UPDATE或者DELETE操作。
这个UPDATE会一直等待A连接执行commit或者rollback才会生效。
我觉得获得了这个锁是可以防止事务B的修改,可我不明白为什么事务A自己修改的时候会报错发现死锁
如果非要理解,我只能这么理解:
1、就是说事务B优先进入了等待X锁的队列,而事务A排在它后面,因此只要B获取不了X锁,A肯定获取不到
2、A锁持有S锁,因此B也不可能获得X锁这样就发生死锁了
2. A 的delete等待B释放排他锁
Deadlock occurs here because client A needs an X lock to delete the row. However, that lock request cannot be granted because client B already has a request for an X lock and is waiting for client A to release its S lock. Nor can the S lock held by A be upgraded to an X lock because of the prior request by B for an X lock. As a result, InnoDB generates an error for client A and releases its locks. At that point, the lock request for client B can be granted and B deletes the row from the table.