请教一个 mysql 的死锁问题

 我来答
lilipat
高粉答主

2017-11-28 · 每个回答都超有意思的
知道大有可为答主
回答量:3万
采纳率:94%
帮助的人:4983万
展开全部

我之前对死锁的理解一般情况就是A事务锁定了行a,B事务锁定了行b,然后这时A事务请求行b的锁,B事务请求行a的锁,就会HANG住不动,这就产生了死锁。
最近刚刚接触MYSQL,今天在看文档的过程中看到文档中举得一个死锁的例子,如下

SQL code?

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455

下列的例子演示当锁定请求可能会导致死锁之时一个错误会如何发生。例子中包括两个客户端A和B。<br data-filtered="filtered"><br data-filtered="filtered">首先客户端A创建一个包含一个行的表,然后开始一个事务。在这个事务内,A通过在共享模式选择行获得对行的S 锁定:<br data-filtered="filtered"><br data-filtered="filtered">mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;<br data-filtered="filtered"><br data-filtered="filtered">Query OK, 0 rows affected (1.07 sec)<br data-filtered="filtered"><br data-filtered="filtered"> <br data-filtered="filtered"><br data-filtered="filtered">mysql> INSERT INTO t (i) VALUES(1);<br data-filtered="filtered"><br data-filtered="filtered">Query OK, 1 row affected (0.09 sec)<br data-filtered="filtered"><br data-filtered="filtered"> <br data-filtered="filtered"><br data-filtered="filtered">mysql> START TRANSACTION;<br data-filtered="filtered"><br data-filtered="filtered">Query OK, 0 rows affected (0.00 sec)<br data-filtered="filtered"><br data-filtered="filtered"> <br data-filtered="filtered"><br data-filtered="filtered">mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;<br data-filtered="filtered"><br data-filtered="filtered">+------+<br data-filtered="filtered"><br data-filtered="filtered">| i    |<br data-filtered="filtered"><br data-filtered="filtered">+------+<br data-filtered="filtered"><br data-filtered="filtered">|    1 |<br data-filtered="filtered"><br data-filtered="filtered">+------+<br data-filtered="filtered"><br data-filtered="filtered">1 row in set (0.10 sec)<br data-filtered="filtered"><br data-filtered="filtered">接着,客户端B开始一个事务并尝试从该表删除行:<br data-filtered="filtered"><br data-filtered="filtered">mysql> START TRANSACTION;<br data-filtered="filtered"><br data-filtered="filtered">Query OK, 0 rows affected (0.00 sec)<br data-filtered="filtered"><br data-filtered="filtered"> <br data-filtered="filtered"><br data-filtered="filtered">mysql> DELETE FROM t WHERE i = 1;<br data-filtered="filtered"><br data-filtered="filtered">删除操作要求一个X 锁定。因为这个锁定不兼容客户端A持有的S锁定,所以X 锁定不被允许,所以请求进入对行及客户端阻挡的锁定请求队列。<br data-filtered="filtered"><br data-filtered="filtered">最后,客户端A也试图从表中删除该行:<br data-filtered="filtered"><br data-filtered="filtered">mysql> DELETE FROM t WHERE i = 1;<br data-filtered="filtered"><br data-filtered="filtered">ERROR 1213 (40001): Deadlock found when trying to get lock;<br data-filtered="filtered"><br data-filtered="filtered">try restarting transaction



客户端A首先对i=1那一行获取了S锁,然后客户端B在delete的时候尝试获取X锁就会进入等待,直到这一步我还是能理解的。可是后来在客户端A尝试删除i=1的数据行的时候,却报发生了死锁的错误,这是为什么呢?

lock in share mode称为共享锁

for update称为排他锁
当事务中包含select ...lock in share mode的时候,相关记录将会被锁住,不允许进行修改。

这个语句限制在事务表的其他连接上进行UPDATE或者DELETE操作。
这个UPDATE会一直等待A连接执行commit或者rollback才会生效。

事务A获得了这个共享锁,自己也不能修改吗?
我觉得获得了这个锁是可以防止事务B的修改,可我不明白为什么事务A自己修改的时候会报错发现死锁

因为客户端A需要一个X 锁定来删除该行,所以在这里发生死锁。尽管如此,锁定请求不被允许,因为客户端B已经有一个对X锁定的请求并且它正等待客户端A释放S锁定。因为客户端B之前对X 锁定的请求,被客户端A持有的S锁定也不能升级到X锁定。因此,InnoDB对客户端A产生一个错误,并且释放它的锁定。在那一点上,客户端B的锁定请求可以被许可,并且客户端B从表中删除行。 “

这是文档里关于上面这段代码解释的一段话
如果非要理解,我只能这么理解:
1、就是说事务B优先进入了等待X锁的队列,而事务A排在它后面,因此只要B获取不了X锁,A肯定获取不到
2、A锁持有S锁,因此B也不可能获得X锁

这样就发生死锁了

  1. B 等待A释放共享锁

    2. A 的delete等待B释放排他锁

可是B并没有获得排他锁啊,因为B也在等待A的共享锁释放以后他才能获得排他锁

所以我更倾向于我前面说的那种解释,A和B都在等待排他锁,只不过B排在A前面

个人观点,欢迎讨论

A连接没有执行commit或者rollback,一直是锁定状态

恩 是的 不过此时A获取的也只是S锁定吧

我的理解如我#3所描述的那样,请帮忙看下那样理解正确吗?

看下英文的文档感觉更明朗些了
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.

grace23450
2017-11-28 · TA获得超过1.3万个赞
知道大有可为答主
回答量:7081
采纳率:77%
帮助的人:2322万
展开全部
说说看,什么情况下出现的死锁
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式