当前位置: 首页 > 科技观察

日常BUG排查-应用提交错误报告事务不回滚

时间:2023-03-21 20:48:52 科技观察

日常BUG排查系列是一些简单的BUG排查,笔者将在这里介绍一些简单的BUG排查技巧,顺便积累素材_。应用Commit报错不一定回滚。事实上,本文没有任何故障排除过程。但是这个问题是笔者经常遇到的。笔者只是想说明一下,当我们在事务Commit中报错时,数据库中的数据不一定是我们认为的回滚状态。作者举了个例子:在这种情况下,很明显DB数据一定是提交状态。但是,如果App认为自己是回滚状态,根据这些信息进行操作,显然会导致数据不一致。非IO或超时异常不一定回滚。可能有人会问,难道只有IO异常或者超时异常不一定回滚吗?这不一定是真的。笔者在一个案例中,发现Oracle在commit时返回死锁异常时,数据库内部的commit也成功了!这就涉及到数据库的内部处理。应用程序应该做什么?其实是因为数据库保证了原子性。所以当我们遇到这种情况时,我们需要从数据库中重建状态,而不是依赖当前应用中的信息。所以遇到异常直接结束流程,等待定时任务等订单补货操作,是比较简单和安全的。当然,在数据库中重建状态的时候,还要考虑到之前对应的commit还在commit过程中,但是这次commit很慢。因为我们在更新数据或者做最终判断的时候经常会加锁数据,所以数据库一般使用两级锁(S2PL)。最后一次commit提交成功后,我们对相应数据的操作就会执行。所以只要小心控制锁的范围,还是可以保证数据一致性的。综上,Commit报错但是事务没有回滚。虽然这有点反直觉,但在生产线上确实存在,尤其是在数据库压力大的时候。这个坑我们写代码的时候需要牢记!本文转载自微信公众号《Bug解决之路》,可通过以下二维码关注。转载本文请联系BUG解决公众号。