前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Deadlock found when trying to get lock; try restarting transaction

Deadlock found when trying to get lock; try restarting transaction

原创
作者头像
小马哥学JAVA
发布2022-12-01 15:16:50
6290
发布2022-12-01 15:16:50
举报
文章被收录于专栏:JAVA开发专栏

报错详情

Error updating database.  Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

The error may involve com.iss.cms.fdrb.common.dao.entity.InterfaceQueue.updateInterfaceQueue-Inline

The error occurred while setting parameters

SQL: update t_fdrb_interface_queue t  set       t.send_status = ?,       t.update_time = ?       where tenant_id = ? and biz_code= ? and biz_id = ? and send_status in (1,3)

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

; 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; try restarting transaction at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:267) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73) at org.mybatis.spring.SqlSessionTemplate

Proxy147.update(Unknown Source)

MySql锁类型的介绍

上面是MySql锁表的问题报错日志,今天记录一下解决方案。

  1. 行级锁在使用的时候并不是直接锁掉这行表记录,而是锁索引
  2. 如果一条Sql用到了主键索引的话,mysql会锁住这条记录主键索引
  3. 如果一条Sql用到了非主键索引,mysql会先锁住非主键索引,然后再锁定主键索引

原理

mysql的两情况的锁,排它锁与共享锁。

  1. 排它锁是事务T对数据A加上排他锁,只能允许事务T读取和修改数据A,别的事务没有办法进行读取与修改的操作处理,所以叫做排他锁,是互斥的
  2. 共享锁是事务T对数据A加上共享锁,其他事务只能再对数据A加上共享锁,而不能进行排它锁的操作,别的事务也可以加上共享锁。是不会进行互斥的

一般造成死锁的原因是因为两个事务添加了锁的时候没有及时进行释放锁资源,等到第二个事务要添加排他锁的时候,发现已经被锁了,从而导致的环路等待,构成死锁

问题的排查过程

日志定位可以找到具体的表是什么,然后定位这

从表里面可以发现进行更新的时候,没有用到索引,而是使用两个非索引,类似聚合索引的方式进行更新的处理。

问题的解决方案

针对这种情况,需要进行调整,先查询出来这一条记录,然后根据主键来进行更新的操作即可。

更改Sql之前

update t_fdrb_interface_queue t set t.send_status = ?, t.update_time = ? where tenant_id = ? and biz_code= ? and biz_id = ? and send_status in (1,3)

更改Sql之后

update t_fdrb_interface_queue t set t.send_status = ?, t.update_time = ? where Id=?

这里备注一下,后续在操作更新的操作时,要使用索引进行更新,避免死锁的情况

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 报错详情
  • MySql锁类型的介绍
  • 原理
  • 问题的排查过程
  • 问题的解决方案
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档