项目中的问题发现
接口响应时间超长,耗时几十秒才返回错误提示,后台日志中出现错误日志:
Lock wait timeout exceeded; try restarting transaction
出现问题的场景
1.在同一事务内先后对同一条数据进行插入和更新操作;
2. 多台服务器操作同一数据库;
3.瞬时出现高并发现象
4.执行DML操作没有commit,再执行删除操作就会锁表
5.事务中嵌套事务或者事务中依赖第三方接口导致事务时间超过默认配置值
出现问题的原因
1.在高并发的情况下,Spring事物造成数据库死锁,后续操作超时抛出异常
2.Mysql数据库采用InnoDB模式,默认参数:innodb_lock_wait_timeout设置锁等待的时间是50s,一旦数据库锁超过这个时间就会报错
解决方案
1.查找当前活跃事务
根据trx_started等判断事务是否异常锁定
SELECT * from information_schema.INNODB_TRX
2.杀死线程
Kill id(上面查询出来的trx_mysql_thread_id)
总结
- 事务中的代码业务逻辑不要太长(或者嵌套的方法太多)
- 很容易导致事务超时或者增删改了同一条sql
- 代码逻辑主次要分清。(事务中的逻辑尽量短小,需要请求其他三方平台的接口可考虑异步化)
- 尽可能将业务放到同一个事务当中,不然容易出现死锁现象