由事务引起的心跳事件

最近在项目中发现一个比较严重的问题,当然之前也意识到了,已更正,不过还没上到生产环境,但在业务中发现了其巨大的威力。

大概代码结构如下:

@Transaction(REQUES_NEW)
A() {
    for() {
        B();
    }
}

B() {
    some code;
    C();
    some DB update actions;
}

@Transaction(REQUES_NEW)
C() {
    call 第三方API,插入业务数据并记log到DB
}

最近发现由于B方法中some code中一些代码运行异常抛出没catch导致事务的回滚,而又由于B方法在for循环中,会导致所有循环到的全部回滚,而这里面会有成功的情况,其实不应该回滚的。另外,也看出异常处理也有问题,应该try catch起来的。所以导致很多数据已经比较久的没有被更新到,当发现以后,还是很严重的,毕竟业务人员是比较关心C方法中call API的返回结果的,当时也被吓了一跳,这个是事务引起的第一次心跳事件,认识到事务使用不当会造成业务上的“乱杀”。

之后我们找到那条处理不了的循环数据并做了手动处理,然后再调用相关方法,发现此时因为事务加在for循环下,而且堆积了大量的数据,那么此时循环执行完的时间会比较久,而且之后事务一次性commit的数据会相当庞大,那么此次事务就会很重,给DB造成的压力也会很重,而且一旦再出现某条数据处理不了,那么就会再次出现上面的问题,而且在事务未提交之前是无法立刻看到数据更新的效果的,所以只能等,那等的时候就是事务引起的第二次心跳事件,整个人都不好了,认识到事务使用不当加异常处理不到位会造成业务上的“风险”和“不必要的巨大压力”。

此时应该这样优化:


A() {
    for() {
        B();
    }
}


@Transaction(REQUES_NEW)
B() {
    try {
        some code;
        C();
        some DB update actions;
    } catch() {
        记log,发邮件通知相关support人员去处理等
    }
    
}

@Transaction(REQUES_NEW)
C() {
    call 第三方API,插入业务数据并记log到DB
}

事务这块还要继续学习,例如:不同类型的区别和使用场景等。也是很有研究价值和业务价值的一个技术啦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章