事务操作时中断导致锁表
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 删除就不在锁表了。