一次启用事务 begin 没有 commit 的事故🐬
条评论最近在公司接到了一个工单,表象是运营人员在配置一个表单的时候执行一个接口请求,所有的日志和返回都是正确,但是 update
和 insert
语句都没有执行,日志系统却都追踪到执行了此语句。更奇怪的是,这个接口的前半部分都执行成功,后半部分都失败了。如下中语句1、语句2、语句3、都成功了。语句4、语句5、语句6都失败了。
问题
伪代码如下:
|
|
排查
拿到这个问题按照经验来讲,就是通过几个方面来排查:
- 代码问题,是否有bug
- 是否启用了事务,执行失败导致回滚。
- 是否是因为数据库配置了主从,
update
和insert
的主表,select
的从表,但是主从不一致。
随后和架构师以及运维沟通,排除了3,数据库日志都显示正常。那就去排查2,发现虽然代码中有一个事务,但是并不影响主流程的执行。1排查了半天,由于是老代码,且写代码的人离职了,所以并不能仔细的追踪到问题点。
于是就造了一些数据,把线上的拉到本地执行,发现了问题的真正所在:1+2一起造成了这次bug。
原因
在语句3之后开启了事务,参数 $parameters[xx] = null
的时候,加了一个判断,问题是在判断之后,直接返回了个true,也就是说此时开启了事务,随后所有的语句都会掉到这个事务中,由于一直没有commit,语句4和语句4以后的sql都得不到执行。在长时间没有执行的情况下,sql语句会自动回滚。相当于语句4和语句4以后的sql都没有执行。但是只从代码上看,语句5、语句6的确是执行到了。
所以 实际上,本次事故,的原因是有两个:
- 第一是代码问题。
- 第二是我们的日志系统没有追中到事务的执行,只是单纯的记录了sql的执行。
修复
直接修复代码即可。使用事务,一定要完整且闭合。
本文标题:一次启用事务 begin 没有 commit 的事故🐬
文章作者:qianyugang
发布时间:2022-03-08
最后更新:2023-06-16
原始链接:https://102no.com/2022/03/08/mysql-begin-no-commit/
版权声明:本网站发表的全部原创内容(不仅限于文章、图片,包含文章评论),著作权均归其发表者所有,均采用 CC BY-NC-SA 4.0 CN 许可协议。转载请注明作者以及原文链接,商业授权请联系作者。
分享