MySQL事务锁出现的问题、Lock wait timeout exceeded; try restarting transaction

什么问题?

后台日志打印出这样的问题。 Lock wait timeout exceeded; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction

什么场景?

  • 页面上修改信息,Java端需要通过mq下发任务到底层C++,C++负责执行任务

  • 第一次发出修改请求,底层C++未返回任何信息,后台日志没有任何日志打印

  • 第二次发出修改请求,报出Lock wait timeout exceeded; 

什么原因?

第一次请求事务A执行过程中,通过mq下发任务给C++端,但是没有任何信息(成功、失败)返回,导致事务A一直处于running状态。没有commit也没有rollback。

第二次请求事务B拿不到锁,因为事务A一直处于执行中,没有释放事务锁,所以事务B就等待1分钟超时了。

### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
; Lock wait timeout exceeded; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:262)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
    at com.sun.proxy.$Proxy155.update(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:294)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
    at com.sun.proxy.$Proxy205.updateByPrimaryKeySelective(Unknown Source)
    at com.byavs.drwisas.business.dao.PetitionPersonMapper.updateByPrimaryKeySelective(PetitionPersonMapper.java:97)
    at com.byavs.drwisas.business.service.PetitionPersonService.update(PetitionPersonService.java:301)
   解决方法:

因为C++端没有打开联通接口,所以也不会返回任何信息、无论成功或是失败。然后Java端这边事务处理就没有commit和rollback,这样就一直占用事务锁,导致其他事务拿不到锁。

这种情况需要解决,但是mq里没有等待超时的处理,所以需要设置一个默认时间,当没有任何信息返回的时候,Java端直接抛出异常,触发事务rollback操作,同时释放事务锁

扩展

网上有很多遇到这个这个问题是因为同一时间内对同一条数据做修改和删除的操作导致的。瞬间出现高并发的现象导致的死锁,我这种情况是因为第一次请求的事务一直在running中。导致往后的请求都lock wait timeout exceeded。

***查看数据库当前的进程

mysql> show processlist;

查看数据库当前的进程

***查看所有运行中的事务

mysql> SELECT * FROM information_schema.INNODB_TRX;

运行中的事务

***查看当前出现的锁

mysql> SELECT * FROM information_schema.INNODB_LOCKs;

查看当前出现的锁

此时我们再次发起请求、查看所有运行中的事务

查看运行事务

这时候就出现等待锁,这就是因为第一次请求的事务锁一直处于运行中,还未释放,第二次请求就只能等待了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值