zoukankan      html  css  js  c++  java
  • 日常Bug排查-应用Commit报错事务并没有回滚

    日常Bug排查-应用Commit报错事务并没有回滚

    前言

    日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_

    应用Commit报错并不一定回滚

    事实上,这篇文章并没有什么排查过程。但这个问题却又是笔者经常遇到的。
    笔者仅仅是想阐述一下当我们在事务Commit报错时候,数据库中的数据并不一定会是我们以为的回滚状态。笔者举个例子:

    在这种情况下,很明显的DB的数据肯定是处于已经提交的状态。而如果App认为是回滚状态,并基于这个信息去做操作的话,很明显会导致数据不一致。

    非IO or 超时异常 也不一定回滚

    可能有人会问了,是不是仅仅是IO异常或者超时异常才会出现这种不一定回滚的问题呢?这里还真不一定,笔者在一次Case中,就发现Oracle在commit的时候返回死锁异常时候,数据库内部的commit竟然也成功了!这就牵涉到数据库内部的处理了。

    应用应该怎么做呢?

    事实上,由于数据库保证了原子性。所以我们在遇到这种情况时候,需要从数据库中重建状态,而不是依赖现在应用里面的信息。所以遇到异常直接将流程结束,然后等定时任务等补单操作是个比较简单安全的做法。
    当然,数据库中重建状态时候,也要考虑到上一个相应的commit还在commit的过程中,只不过这个commit非常慢而已。由于我们更新数据或者最终判断的时候往往会锁住数据,而数据库一般都是采用了二阶段锁(S2PL)。

    在上一个commit成功提交之后,我们对相应数据的操作才会执行下去。所以只要小心的控制好锁的范围,数据一致性还是能保证的。

    总结

    Commit报错但事务并没有回滚,这个虽然有点反直觉,但这确是在产线真实存在的,尤其在数据库压力大的时候极易出现。这个坑在我们编写代码的时候需要牢记!

  • 相关阅读:
    GO语言并发
    NEERC2017:L
    bzoj2823[AHOI2012]信号塔
    bzoj1336[Balkan2002]Alien最小圆覆盖
    bzoj1069[SCOI2007]最大土地面积
    ACM2017Tsukuba:H
    ACM2015沈阳:B-Bazinga
    bzoj2724[Violet 6]蒲公英
    [bzoj4066]简单题
    [bzoj2125]最短路
  • 原文地址:https://www.cnblogs.com/alchemystar/p/14884250.html
Copyright © 2011-2022 走看看