大家好,又见面了,我是你们的朋友全栈君。
这个问题之前遇到过一次,但是由于不知道导致锁表的原因,也没细想,就知道表被锁了,然后让别人把表给解锁了。但是前天的一次操作,让我亲眼见证了导致锁表的过程,以及如何给lock的表解锁。
1.导致锁表的原因(同志们也可以参考是不是也是同样的操作啊。。。):
- 1.1首先是大前提
我们正常的框架在service层都会有事物控制,比如我一个service层的方法要执行更新两张表,这两个表只有同时更新成功才算成功,如果有一个异常,事务回滚。
- 1.2 我的操作
这是源代码的部分,当debug到sysEleMaterialClassService.updateChildParentId();
出现异常,然后在catch里我打了个断点,看报错信息。看完之后没有走到 throw这个抛异常的方法,然后我就关闭了应用,修改代码。等重启后就发现表锁了。
我这个操作就导致即没有抛异常让事务回滚,也没有让mybatis提交事务,但是表这是已经被锁定,等着你提交后执行,就这么一直等着,始终没有提交。 mybatis 对 jdbc 的代码做过封装,它的事务提交时手动的,所以我们每次要sqlSession.submit();而这一步应该是走完方法到controller层后才提交。我这里到service层就停了。
- 1.3 报错信息
再次启动程序还是能够查询,但是对update ,insert的操作已经执行报错:
Lock wait timeout exceeded; try restarting transaction
2.解决锁表问题
- 2.1 先用这条命令查询数据库阻塞的进程
SELECT * FROM information_schema.innodb_trx
得到的数据如下:
- 2.2
主要看箭头指向的这几个字段,如果有阻塞数据(不为0的就是阻塞的),找到后在根据下图这个字段:try_mysql_thread_id
作为这条数据的主键id执行这个sql进行删除: kill id ;
(杀死对应id的进程).假设这里try_mysql_thread_id=277
的这条数据是锁了。我们执行 kill 277
删除就不在锁表了。
本片博客参考:mysql 事务未提交导致死锁 Lock wait timeout exceeded; try restarting transaction 解决办法
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/172318.html原文链接:https://javaforall.cn