我有一个account
表,其中有1行。
我有2个线程可以做下一个:
第一个线程:
begin transaction;
select * from account where balance=0 for update;
UPDATE account SET balance = 10 WHERE balance=0;
// waiting here for several seconds
commit transaction;
第二个线程:
begin transaction;
select * from account where balance=0 for update;
commit transaction;
下一个是流程:
1)第一个线程启动并前进到waiting here for several seconds
行。
2)第二个线程启动并被阻止(从逻辑上讲,因为第一个线程尚未释放悲观锁)。
3)第一个线程成功提交事务。
4)第二个线程出错:ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
在这种情况下,如果没有死锁,为什么会出现死锁异常?我在所有4个事务隔离级别上尝试了这种情况,并在所有隔离级别上都获得了相同的错误。
答案 0 :(得分:1)
问题是我的错误。所以上面的代码实际上应该工作。
我的问题是我在第一个线程中使用了lock in share mode
,在第二个线程中使用了for update
。我以为它们是相同的,但实际上不是。当我将第一个线程也改为使用for update
时,它们开始正常工作。
感谢Shadow给出了使用innodb状态监视器检查死锁事务信息(SHOW ENGINE INNODB STATUS;
)的提示。