生产线上问题:用户在发起一个流程时发现提交一直转圈,于是一直在点(这里没有实现防重复提交),产品喊我去看一下,我一看slow sql 2min, 开始还以为是慢查询导致的超时,请求中止,准备看业务逻辑,就让用户先保存下数据,准备自己操作一下看下日志,然后用户一点保存就报错
Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:271)
我一看好家伙还死锁了,赶紧看业务逻辑,原来是这个调用链路比较长,方法比较长,里面各种保存附件,流程信息、查询等还加了个@Transational, 这个方法本来就长了还得等执行完了才能提交事务,那么这个表不就一直处于被锁状态,然后用户频繁操作,其实一直是在操作那一行,其次这个里面还有两个坑就是用户提交的附件太多了(9个),然后这个提交的流程是到另外一个系统的,这块的调用是一个同步调用,一直得不到第三方系统的响应,数据库事务无法提交。
解决方案:
1、提交和保存增加防重复提交
2、避免在长方法添加@Transational
3、调用第三方系统一定是异步的
4、就是前端限制用户上传的附件数量
5、在插入操作的事务方法上配置重试
前面四件点都是针对业务的优化,最后一点是从技术角度进行兜底。
但是从日常的开发角度来说,业务上的优化比技术的优化更有效,在开始设计和开发时就要考虑到未来生产环境遇到的一些问题,而不是说给后人埋下许多地雷。
232

被折叠的 条评论
为什么被折叠?



