记录死锁问题

发表于
4

在某系统批量跑批处理数据的时候,偶尔会报错提示:Error updating database. Cause: com.mysql.jdbc.exception.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

通过执行SQL命令查询具体死锁的内容:SHOW ENGINE INNODB STATUS;

排查:WAITING FOR THIS LOCKHOLDS THE LOCK(S) 找到了对应两个死锁的事务。

主要原因就是:索引有问题。

某个表有两个索引:idx_shop_id(shop_id)idx_del(del)

在并发跑批的时候:update table_name set show = 0 where shop_id = 123456 and del = 0 and other_field = xxxupdate table_name set show = 0 where shop_id = 678901 and del = 0 and other_field = xxx

其中一个根据shop_id索引遍历加锁,一个根据del索引遍历加锁。
比如:

  1. 事务 A

    • 锁住 id=1,2(shop_id = 678901

  2. 事务 B

    • 锁住 id=3,4(del = 0

  3. 接下来:

  • A 想锁 id=3(被 B 持有)

  • B 想锁 id=2(被 A 持有)

解决方案就是加联合索引:idx_shop_id_del(shop_id,del)


0