下面是通过错误日志捕捉到的死锁SQL:
150922 18:12:49
事务1
update g_taskinfo set tislocked=1,tlockperson=13406 where tobjnum2 = 94064033 and tislocked = 0
使用到idx_tobjnum2_ttape索引(非主键索引)
事务2
update g_taskinfo set finishtime='2015-09-22 18:12:28', tstatus=20 where id=471791 (使用到主键索引)
事务1 update操作过程
1、由于使用了非主键索引,首先需要获取idx_tobjnum2_ttape上的行级锁
2、紧接着根据主键进行更新,所以需要获取主键上的行级锁
3、更新完毕后,提交,并释放所有锁(MySQL锁一次性释放)
死锁产生原因:
高并发场景下,事务1的步骤1执行完后,锁住了非主键索引,然后去请求主键索引,此时在执行完步骤1后,进入步骤2之前突然进来事务2,事务2会锁住主键索引,然后去请求非主键索引idx_tobjnum2_ttape。
由于事务2获取了主键索引,在等待idx_tobjnum2_ttape上的锁。
事务1获取了idx_tobjnum2_ttape锁,等待主键索引上的锁。
死锁发生。
解决方法:将事务1的非主键索引,修改为通过主键逐一操作
网友评论