【发布时间】:2021-06-08 18:25:24
【问题描述】:
我有两个线程,它们必须更新同一张表,但第一个线程使用主键锁定单个记录,第二个线程必须使用另一个索引锁定一组记录。锁是用 SELECT ... FOR UPDATE 语句制成的,我不明白他们为什么会陷入死锁。
这是桌子:
CREATE TABLE `ingressi` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`evento` int(10) unsigned NOT NULL,
`stato` int(10) unsigned NOT NULL,
....,
....,
PRIMARY KEY (`id`),
KEY `evento` (`evento`,`stato`) USING BTREE,
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
这是查询日志(请注意连接):
43 Query SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
43 Query set autocommit=0
43 Query SELECT stato FROM ingressi WHERE id=1 FOR UPDATE
39 Query SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
39 Query set autocommit=0
39 Query SELECT count(*) FROM ingressi WHERE evento=66 FOR UPDATE
43 Query UPDATE `ingressi` SET stato=0 WHERE id=1
43 Query COMMIT
就在最后一次查询之后引发死锁错误。
(conn=39) 尝试获取锁时发现死锁;尝试重新启动 交易
43 和 39 连接是使用连接池的 Spring-Java 应用程序的 JDBC 连接。
为什么第二个连接不等待而死锁?
【问题讨论】:
-
你能把
SHOW CREATE TABLE tab的结果加起来吗?所以我们不必猜测或假设您在表中有哪些索引。 -
我刚刚用真实数据和查询编辑了这个问题,以便您了解如何设置索引。抱歉,我没有考虑索引的重要性。
标签: mysql transactions deadlock