问题背景:外网mysql在执行玩家保存数据的存储过程时,出现死锁 Deadlock found when trying to get lock; try restarting transaction
产生原因:两个线程AB提交事务时,对同一张表 test_deadlock(表名为化名)进行了如下操作:
A线程根据表主键进行插入更新(insert into ON DUPLICATE KEY UPDATE ),此时为行锁,
B线程对表进行删除部分数据(并不是根据主键),此时为表锁,
A线程对表进行删除部分数据(并不是根据主键),此时为表锁。此刻,B线程错误提示死锁。
重现过程:
CREATE TABLE `test_deadlock` ( `a` int(11) NOT NULL, `b` int(11) NOT NULL, `c` int(11) NOT NULL, PRIMARY KEY (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `test_deadlock`(a,b,c) values(4,4,4) ON DUPLICATE KEY UPDATE b=4,c=4; insert into `test_deadlock`(a,b,c) values(3,3,3) ON DUPLICATE KEY UPDATE b=3,c=3; insert into `test_deadlock`(a,b,c) values(2,2,2) ON DUPLICATE KEY UPDATE b=2,c=2; insert into `test_deadlock`(a,b,c) values(1,1,1) ON DUPLICATE KEY UPDATE b=1,c=1;
用Navicate 工具,打开AB两个窗口,
A窗口执行:
start TRANSACTION;
insert into `test_deadlock`(a,b,c) values(1,1,1) ON DUPLICATE KEY UPDATE b=1,c=1;
B窗口执行:
update test_deadlock set b = 2 where b = 2;
A窗口执行:
update test_deadlock set b = 4 where b = 4; 此刻B窗口提示死锁。
以上想重复实验,请在A窗口执行:commit;
如何避免死锁:
1.使用事务,但是避免使用长事务,将大事务拆小,分段多提交。
2.sql语句条件是主键或者索引,这样执行后为行锁,避免表锁,从而避免死锁。
innodb死锁1213 - Deadlock found when trying to get lock; try restarting transaction
原文:https://www.cnblogs.com/workharder/p/12830680.html