由事務引起的心跳事件

最近在項目中發現一個比較嚴重的問題,當然之前也意識到了,已更正,不過還沒上到生產環境,但在業務中發現了其巨大的威力。

大概代碼結構如下:

@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
}

事務這塊還要繼續學習,例如:不同類型的區別和使用場景等。也是很有研究價值和業務價值的一個技術啦。

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