使用主键导致死锁的两个重复删除查询

Mar*_*ams 9 mysql deadlock locking

我不明白两个重复的查询如何使用主键对单个表删除单个行可能会死锁.谁能解释一下?

在我看来,其中一个交易应该获得锁定而另一个交易必须等待.

这是死锁报告,包含查询:

Fri Jun 01 2012 13:50:23
*** (1) TRANSACTION:
TRANSACTION 3 1439005348, ACTIVE 0 sec, process no 22419, OS thread id 1166235968 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 368
MySQL thread id 125597624, query id 3426379709 node3-int 10.5.1.119 application-devel updating
DELETE FROM `SessData` WHERE `SessKey` = '87EDF1479A275557AC8280DCA78AB886'
AND `Name` = 'CurrentRequestURL'

*** (2) TRANSACTION:
TRANSACTION 3 1439005340, ACTIVE 0 sec, process no 22419, OS thread id 1234073920 starting index read, thread declared inside InnoDB 0
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1216
MySQL thread id 125597622, query id 3426379705 node2-int 10.5.1.118 application-devel updating
DELETE FROM `SessData` WHERE `SessKey` = '87EDF1479A275557AC8280DCA78AB886'
AND `Name` = 'CurrentRequestURL'

*** WE ROLL BACK TRANSACTION (2)
Run Code Online (Sandbox Code Playgroud)

这是表格的架构:

CREATE TABLE  `application`.`SessData` (
  `SessKey` varchar(255) NOT NULL default '',
  `Name` varchar(255) NOT NULL default '',
  `Value` varchar(255) default NULL,
  PRIMARY KEY  (`SessKey`,`Name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)

其他一些细节:

MySQL version: 4.1.21
Isolation level: REPEATABLE-READ
Character set on the the above columns: latin1
Run Code Online (Sandbox Code Playgroud)

Old*_*Pro 4

您正在使用 MySQL 版本 4.1.21。4.1 已经结束,4.1.21 甚至不是最新的 4.1 版本。(对 MySQL 4.1 的扩展支持已于 2009 年 12 月 31 日结束。)您应该至少升级到 5.0.96,不过您也可以完全更新到 5.5.25。如果做不到这一点,您至少可以升级到4.1.22 ,但这可能无法解决您的问题。

如果您阅读了 MySQL 4.1文档中的最后一个示例,您就会看到如果要删除的行之前已在事务中使用共享锁进行了选择,那么如何会发生这种死锁。同样,如果涉及外键约束,您可能已经获得了共享锁。一般问题是:

A 获取 x 上的共享锁

B 等待 x 上的独占锁。由于A的锁,它必须等待。

A 等待 x 上的独占锁。它必须等待,因为 B 在排他锁队列中位于它前面。

InnoDB处理锁的方式是,当B等待相同的排它锁时,它不会将A的共享锁升级为排它锁,因此这是一个死锁。

或者,当两个语句都尝试删除不存在的行(可能刚刚被前面的第三个重复删除删除)时,您可能会遇到错误。可能与: