日常Bug排查-應用Commit報錯事務並沒有回滾


日常Bug排查-應用Commit報錯事務並沒有回滾

前言

日常Bug排查系列都是一些簡單Bug排查,筆者將在這里介紹一些排查Bug的簡單技巧,同時順便積累素材_

應用Commit報錯並不一定回滾

事實上,這篇文章並沒有什么排查過程。但這個問題卻又是筆者經常遇到的。
筆者僅僅是想闡述一下當我們在事務Commit報錯時候,數據庫中的數據並不一定會是我們以為的回滾狀態。筆者舉個例子:

在這種情況下,很明顯的DB的數據肯定是處於已經提交的狀態。而如果App認為是回滾狀態,並基於這個信息去做操作的話,很明顯會導致數據不一致。

非IO or 超時異常 也不一定回滾

可能有人會問了,是不是僅僅是IO異常或者超時異常才會出現這種不一定回滾的問題呢?這里還真不一定,筆者在一次Case中,就發現Oracle在commit的時候返回死鎖異常時候,數據庫內部的commit竟然也成功了!這就牽涉到數據庫內部的處理了。

應用應該怎么做呢?

事實上,由於數據庫保證了原子性。所以我們在遇到這種情況時候,需要從數據庫中重建狀態,而不是依賴現在應用里面的信息。所以遇到異常直接將流程結束,然后等定時任務等補單操作是個比較簡單安全的做法。
當然,數據庫中重建狀態時候,也要考慮到上一個相應的commit還在commit的過程中,只不過這個commit非常慢而已。由於我們更新數據或者最終判斷的時候往往會鎖住數據,而數據庫一般都是采用了二階段鎖(S2PL)。

在上一個commit成功提交之后,我們對相應數據的操作才會執行下去。所以只要小心的控制好鎖的范圍,數據一致性還是能保證的。

總結

Commit報錯但事務並沒有回滾,這個雖然有點反直覺,但這確是在產線真實存在的,尤其在數據庫壓力大的時候極易出現。這個坑在我們編寫代碼的時候需要牢記!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM