首页 > 解决方案 > 关于 MySQL 事务死锁的说明

问题描述

最近我遇到了引发以下错误的死锁情况。

MySQL 版本:8.0.15

"ER_LOCK_WAIT_TIMEOUT | ER_LOCK_WAIT_TIMEOUT:超过锁定等待超时;尝试重新启动事务

经过审查,我发现与死锁相关的存储过程COMMIT在启动后缺少语句,TRANSACTION如下所示。

BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        ROLLBACK;
        RESIGNAL;
    END;
  START TRANSACTION;
    SELECT ID FROM SomeTable;
 -- COMMIT; -- This line was missing
END

一旦我添加了COMMIT语句,死锁就解决了。

我理解上述问题,因为一旦我开始事务,它将锁定进程并等待直到它到达COMMIT释放锁定的行(如果我错了,请纠正我)。

我遇到的问题是,即使我们错过了 COMMIT 语句,即使死锁有不同的原因,如果查询用以下 2 行包装,MySQL 查询是否会面临死锁?

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
  SELECT ID FROM SomeTable;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

出现上述问题的原因是,我遇到了这样一种情况,即使用上述语句包装了主题查询以执行 NO LOCK 调用,但上述死锁仍然随机发生。

事务隔离级别设置为

SELECT @@GLOBAL.tx_isolation, @@tx_isolation, @@session.tx_isolation;

REPEATABLE-READ作为上述所有场景的结果返回。

我的理解是,如果用READ UNCOMMITTEDand包裹,查询仍然可以正常工作而不会产生任何死锁REPEATABLE READ

请分享您对此的想法。提前致谢。

标签: mysqltransactionsdeadlocksqlexception

解决方案


推荐阅读