1. 程式人生 > >數據庫事務及特性

數據庫事務及特性

故障 系統 tom 包含 變換 程序 tab 系列 工作

數據庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作,要麽完全地執行,要麽完全地不執行。事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向數據的資源。通過將一組相關操作組合為一個要麽全部成功要麽全部失敗的單元,可以簡化錯誤恢復並使應用程序更加可靠。一個邏輯工作單元要成為事務,必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)屬性。


一致性(Consistency)

一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之後都必須處於一致性狀態。

一致性指的是數據處於一種有意義的狀態,這種狀態是語義上的而不是語法上的。

最常見的例子是轉帳。例如從帳戶A轉一筆錢到帳戶B上,如果帳戶A上的錢減少了,而帳戶B上的錢卻沒有增加,那麽我們認為此時數據處於不一致的狀態。

在數據庫實現的場景中,一致性可以分為數據庫外部的一致性和數據庫內部的一致性。前者由外部應用的編碼來保證,即某個應用在執行轉帳的數據庫操作時,必須在同一個事務內部調用對帳戶A和帳戶B的操作。如果在這個層次出現錯誤,這不是數據庫本身能夠解決的,也不屬於我們需要討論的範圍。後者由數據庫來保證,即在同一個事務內部的一組操作必須全部執行成功(或者全部失敗)。這就是事務處理的原子性。

原子性(Atomicity)

原子性是指事務包含的所有操作要麽全部成功,要麽全部失敗回滾,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。

為了實現原子性,需要通過日誌:將所有對數據的更新操作都寫入日誌,如果一個事務中的一部分操作已經成功,但以後的操作,由於斷電/系統崩潰/其它的軟硬件錯誤而無法繼續,則通過回溯日誌,將已經執行成功的操作撤銷,從而達到“全部操作失敗”的目的。最常見的場景是,數據庫系統崩潰後重啟,此時數據庫處於不一致的狀態,必須先執行一個crash recovery的過程:讀取日誌進行REDO(重演將所有已經執行成功但尚未寫入到磁盤的操作,保證持久性),再對所有到崩潰時尚未成功提交的事務進行UNDO(撤銷所有執行了一部分但尚未提交的操作,保證原子性)。crash recovery結束後,數據庫恢復到一致性狀態,可以繼續被使用。

隔離性(Isolation)

隔離性是當多個用戶並發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所幹擾,多個並發事務之間要相互隔離。

即要達到這麽一種效果:對於任意兩個並發的事務T1和T2,在事務T1看來,T2要麽在T1開始之前就已經結束,要麽在T1結束之後才開始,這樣每個事務都感覺不到有其他事務在並發地執行。

在多個事務並行進行的情況下,即使保證了每一個事務的原子性,仍然可能導致數據不一致的結果。例如,事務1需要將100元轉入帳號A:先讀取帳號A的值,然後在這個值上加上100。但是,在這兩個操作之間,另一個事務2修改了帳號A的值,為它增加了100元。那麽最後的結果應該是A增加了200元。但事實上,
事務1最終完成後,帳號A只增加了100元,因為事務2的修改結果被事務1覆蓋掉了。

為了保證並發情況下的一致性,引入了隔離性,即保證每一個事務能夠看到的數據總是一致的,就好象其它並發事務並不存在一樣。用術語來說,就是多個事務並發執行後的狀態,和它們串行執行後的狀態是等價的。

怎樣實現隔離性,原則上無非是兩種類型的鎖:

一種是悲觀鎖,即當前事務將所有涉及操作的對象加鎖,操作完成後釋放給其它對象使用。為了盡可能提高性能,發明了各種粒度(數據庫級/表級/行級……)/各種性質(共享鎖/排他鎖/共享意向鎖/排他意向鎖/共享排他意向鎖……)的鎖。為了解決死鎖問題,又發明了兩階段鎖協議/死鎖檢測等一系列的技術。

一種是樂觀鎖,即不同的事務可以同時看到同一對象(一般是數據行)的不同歷史版本。如果有兩個事務同時修改了同一數據行,那麽在較晚的事務提交時進行沖突檢測。實現也有兩種,一種是通過日誌UNDO的方式來獲取數據行的歷史版本,一種是簡單地在內存中保存同一數據行的多個歷史版本,通過時間戳來區分。鎖也是數據庫實現中最復雜的部分之一。同樣,如果涉及到分布式系統(分布式鎖和兩階段提交是分布式事務的基礎),會比上述場景還要復雜得多。
處。

持久性(Durability)

持久性是指一個事務一旦被提交了,那麽對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。

例如我們在使用JDBC操作數據庫時,在提交事務方法後,提示用戶事務操作完成,當我們程序執行完成直到看到提示後,就可以認定事務以及正確提交,即使這時候數據庫出現了問題,也必須要將我們的事務完全執行完成,否則就會造成我們看到提示事務處理完畢,但是數據庫因為故障而沒有執行事務的重大錯誤。

數據庫事務及特性