Mysql死锁引起的事务未回滚问题 Deadlock found when trying to get lock; try restarting transaction

拼搏现实的明天。 2023-02-24 15:22 97阅读 0赞

MySQL异常,但是事务却没有回滚,事务前半部分执行的SQL在数据库能看到,日志信息如下

  1. org.springframework.dao.DeadlockLoserDataAccessException:
  2. ### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
  3. ### The error may involve com.jzy.kaisafax.trade.invest.dao.TrdInvestRepayEntityMapper.updateByExampleSelective-Inline
  4. ### The error occurred while setting parameters
  5. ### SQL: UPDATE trd_investrepay SET loanRepayId = ? WHERE ( loanId = ? and period = ? )
  6. ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
  7. ; SQL []; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
  8. at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:263)
  9. at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
  10. at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:74)
  11. at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:421)
  12. at com.sun.proxy.$Proxy27.update(Unknown Source)
  13. at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:270)
  14. at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:55)
  15. at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
  16. at com.sun.proxy.$Proxy30.updateByExampleSelective(Unknown Source)
  17. at com.sxjr.common.base.service.BaseService.updateByExample(BaseService.java:77)
  18. at sun.reflect.GeneratedMethodAccessor1054.invoke(Unknown Source)
  19. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  20. at java.lang.reflect.Method.invoke(Method.java:606)

从日志上能很明显的看到出现了死锁,出现了死锁为什么之前已经执行了的SQL没有回滚呢,带着这个问题去了解了一下MySQL的事务回滚,发现有一个参数很重要 innodb_rollback_on_timeout,先查看一下数据的设置:

  1. show VARIABLES like 'innodb_rollback_on_timeout'

70

可以看到这个变量是OFF

查看了一下MySQL的官网对这个参数的解释,大概就是说在MySQL 5.6&5.7中默认值为OFF,当InnoDB默认情况下仅回滚事务超时的最后一条语句。如果innodb_rollback_on_timeout值为ON,则事务超时后将导致InnoDB中止并回滚整个事务。到这儿问题大概就清晰了,因为这个参数,所以这个事务只回滚了最后出现死锁的那条SQL,将这个值改成ON,再测试发现一切正常。

修改方式为:my.ini 文件

innodb_rollback_on_timeout=on
20200709180732476.png​​​​​​​

发表评论

表情:
评论列表 (有 0 条评论,97人围观)

还没有评论,来说两句吧...

相关阅读