一、 异常背景

1、报错信息
Caused by: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: Lock wait timeout exceeded; try restarting transaction
	at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:184)
	at org.quartz.impl.jdbcjobstore.DBSemaphore.obtainLock(DBSemaphore.java:113)
	at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:238)
	at org.quartz.impl.jdbcjobstore.JobStoreSupport.clearAllSchedulingData(JobStoreSupport.java:2002)
	at org.quartz.core.QuartzScheduler.clear(QuartzScheduler.java:1547)
	at org.quartz.impl.StdScheduler.clear(StdScheduler.java:239)
	at com.ruoyi.quartz.service.impl.SysJobServiceImpl.init(SysJobServiceImpl.java:40)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:123)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
	at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
	at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1003)
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3240)
	at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_executeQuery(FilterEventAdapter.java:465)
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3237)
	at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.executeQuery(PreparedStatementProxyImpl.java:181)
	at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeQuery(DruidPooledPreparedStatement.java:227)
	at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:123)
2、出现背景   

我们项目是一个springboot项目,使用的是若依的后台管理系统  ,项目中使用了定时任务,平时没有出现问题,但是我在调试我的代码时,重启下项目一直无法重启一直报以上错误;查看报错位置,找到报错的是一个若依的系统调用定时任务时发生报错;


二、 异常分析 

 其实报错之前我是能正常是使用的,就突然重启就不可以了,而且我前端时间在数据库mysql中发生过好像类似的错误,数据库事务 死锁问题,所以我感觉应该是数据库事务问题,之后发现确实是事务问题,但是出于谨慎起见我排查了服务器问题,发现服务器链接正常,数据库也能正常链接;

之后我就去数据库里面查询了数据库的事务执行情况和锁的对对应的发现定时任务的事务一直是等待状态


三、 异常解决

1、查询事务

我查询了运行的所有事务,发现有一个是锁等待状态,且还有两个事务时在进行中的,就有可能造成事务交叉

SELECT * FROM information_schema.INNODB_TRX; – 当前运行的所有事务

2、我手动去执行sql,希望能只想成功将事务执行掉,可是一直执行不通过 
SELECT * FROM QRTZ_LOCKS WHERE SCHED_NAME = 'RuoyiScheduler' AND LOCK_NAME = 'TRIGGER_ACCESS' FOR UPDATE
3、查询锁对应关系
SELECT * FROM information_schema.INNODB_LOCKS; – 当前出现的锁
SELECT * FROM information_schema.INNODB_LOCK_WAITS; – 锁等待的对应关系

4、将占有的事务进程杀掉 kill  trx_mysql_thread_id
kill 36504

杀掉之后我重启系统还是报错,无法启动,然后重新查询事务发现依然是之气那查到的那种情况, 其实我当时没有想到,但是我在写笔记想起来我应该在查询所占用情况时,找到线程然后将事务全部杀掉的。可以试一试哈,

5、重启数据库

如果将事务杀掉的话成功就可以不重重数据库的,而且一般也不能重启的
重启之后,重新启动就就可以运行了,查询事务和锁关系就干净了

 四、 衍生思考

正如以上说的,如果是生产环境中,出现了这个问题,应该如何去做?

主要的是在在测试环境中重现这个问题

1、准备在测试环境复现这个问题,测试开启之前,查询是否有未提交事务

2、

-- 查看正在锁的事务(没有)
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; 

-- 查看等待锁的事务(没有)
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

3、测试环境,制造未提交事务,把程序debug挂起

4、再次查看:show PROCESSLIST
5、执行查询未提交事务语句:select * from  information_schema.INNODB_TRX;

事务
1、事务过程中执行其他非数据库操作,导致事务长期未被处理。
2、事务处理异常或实现逻辑有误,导致事务未被正常处理。
3、网段异常导致应用端请求未被正常发送给数据库,数据库等待应用后续操作。
4、应用服务器性能问题(如CPU爆满),导致应用无法及时切换到该进程进行处理。

 

参考帖:https://blog.csdn.net/weixin_39827589/article/details/113489406

MySQL Transaction--查看未提交事务执行的SQL - TeyGao - 博客园

https://segmentfault.com/a/1190000022442121

MySql Lock wait timeout exceeded该如何处理? - 凝雨 - Yun
https://blog.csdn.net/lejustdoit/article/details/120276851

 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐