事務(Transaction) 是由一系列對系統中數據進行訪問與更新的操作所組成的一個程序執行線邏輯單元;是指作爲單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。 事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向數據的資源。通過將一組相關操作組合爲一個要麼全部成功要麼全部失敗的單元,可以簡化錯誤恢復並使應用程序更加可靠。一個邏輯工作單元要成爲事務,必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)屬性。
- Atomicity原子性:一個事務的所有系列操作步驟被看成是一個操作,也就是一個原子操作。
- Consistency一致性:如果兩個以上數據表有關聯,那麼更新一個表同時另外一個表也要一起更新。
- Isolation隔離性:隔離狀態執行事務,使它們好像是系統在給定時間內執行的唯一操作。如果有兩個事務,運行在相同的時間內,執行相同的功能,事務的隔離性將確保每一事務在系統中認爲只有該事務在使用系統。
- Durability持久性:在事務完成以後,該事務對數據庫所作的更改便持久的保存在數據庫之中,並不會被回滾。
銀行轉賬用例
李雷向韓梅梅轉賬100元
故事的原初
李雷和韓梅梅分別在數據庫中有一條記錄,假定李雷賬戶是pk=1 ,有200元; 韓梅梅的賬戶是pk=2,有100元。
一切的數據資源表現爲持久的數據存儲。通俗來講所有人的錢只是銀行IT系統中數據庫的一條記錄;如果所有銀行的數據丟失並且無法恢復,所有人都的一無所有;真正實現了平等 ?
所以這裏涉及了事務的一個特性“持久性”,數據的狀態在沒有業務觸發的情況下必須持久保存,不能丟失。
執行用例
一個程序員開心寫了一個代碼,運行在火星人民銀行的系統中:
開始
查看李雷是否有一百元
李雷賬號pk=1減少100元
韓梅梅賬號pk-=2增加100元
結束
期望結果
在數據庫中李雷賬戶有100元,韓梅梅賬號有200元。
異常場景1
在執行完第二行代碼“李雷賬號pk=1減少100元”後,火星人民銀行機房停電,第二行沒有繼續執行。系統重啓後查詢數據發現在數據庫中李雷賬戶有100元,韓梅梅賬號有100元。系統中有100元不翼而飛 ?
這裏破壞了事務的 “原子性”。
異常場景2
發起轉賬後,李雷迫不及待的查看自己賬戶。當看到自己的賬戶減少了一百塊以後,李雷問電話那頭的梅梅:“梅梅,我看我這裏操作成功了,你那裏收到錢了沒?” 。 如果這時候梅梅跟李雷說:"雷~ 我沒看見我賬戶的錢有變化啊“。
這裏事務的 “一致性” 沒有保證。其他用戶看到了事務三步操作過程中的中間狀態信息,這種信息是明顯反用戶常識的,所以應該儘可能被避免。
異常場景3
在李雷給韓梅梅轉賬時,李雷的立即向魏華轉賬200(別問我爲什麼,我都不知道魏華是誰)。火星人民銀行的系統再次執行程序員“開心”的代碼,當執行查看李雷是否有兩百元時,給韓梅梅轉賬的程序還沒有執行完第二行“李雷賬號pk=1減少100元”,所以這時結論是李雷有兩百元,程序繼續執行“李雷賬號pk=1減少200元”。
這裏事務的 “隔離性” 沒有保證。這種屬性有時稱爲串行化,爲了防止事務操作間的混淆,必須串行化或序列化請求,使得在同一時間僅有一個請求用於同一數據。
總結
程序員開心非常的不開心,他覺得自己的代碼沒有問題,在他那裏跑得很正常,無法接收生產上詭異的問題,肯定是大家調用的姿勢不對。他去想另一個程序員窮開心傾訴,窮開心一下把問題提升到信仰的高度。
事務ACID特性可能遭到破壞的因素有:
- 多個事務並行運行時,不同的事務操作交叉執行;
- 事務在運行過程中被強行停止。
在第一種情況下,系統必須保證多個事務的交叉運行不影響這些事務的原子性;在第二種情況下,必須保證被強行終止的事務對系統和其他事務沒有任何影響。
聽罷,開心茅塞頓開。
然並卵,臣妾做不到啊。。。