MySQL 按照主键更新报Deadlock错误原因分析

这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

问题描述

报错信息很简单在执行update操作语句的时候报错。

Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock;

lQLPDhrgKxz8mX3NAe_NBb6wVHF5PgQasK8BnIUznEBYAA_1470_495.png

MySQL锁介绍

MySQL有三种锁的级别:页级、表级、行级

image.png

  1. 行级锁在使用的时候并不是直接锁掉这行记录,而是锁索引
  2. 如果一条sql用到了主键索引(mysql主键自带索引), mysql会锁住主键索引;
  3. 如果一条sql操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引.

原因分析

报错的原因很简单,我们在按照主键更新表记录的时候,SQL抛了一个死锁的错误。 那就很奇怪按照主键索引更新按道理不会产生错误, 我们观察报错的时间几次都是在凌晨3点左右的时候抛的异常。 3点的时候我们会将这个表的数据做备份,执行delete删除过期的数据,删除数据的时候索引。

参考

最后推荐一个Github维护的一个解决死锁案例汇总的一个项目。 github.com/aneasystone…

Guess you like

Origin juejin.im/post/7031544664154980389