數據庫事務的ACID特性和隔離級別
1. 事務的四個特性
數據庫事務(Transaction)是指作為單個邏輯工作單元執行的一系列操作,要么完全地執行,要么完全地不執行。一方面,當多個應用程序并發訪問數據庫時,事務可以在應用程序間提供一個隔離方法,防止互相干擾。另一方面,事務為數據庫操作序列提供了一個從失敗恢復正常的方法。
事務具有四個特性:原子性(Atomicity)、一致性(Consistency)、隔離型(Isolation)、持久性(Durability),簡稱ACID。
1.1 原子性(Atomicity)
事務的原子性是指事務中的操作不可拆分,只允許全部執行或者全部不執行。
1.2 一致性(Consistency)
事務的一致性是指事務的執行不能破壞數據庫的一致性,一致性也稱為完整性。一個事務在執行后,數據庫必須從一個一致性狀態轉變為另一個一致性狀態。
1.3 隔離型(Isolation)
事務的隔離型是指并發的事務相互隔離,不能互相干擾。
1.4 持久性(Durability)
事務的持久性是指事務一旦提交,對數據的狀態變更應該被永久保存。
2 事務的四個隔離級別
實際工作中事務幾乎都是并發的,完全做到互相之間不干擾會嚴重犧牲性能,為了平衡隔離型和性能,SQL92規范定義了四個事務隔離級別:讀未提交(Read Uncommitted)、讀已提交(Read Committed)、可重復讀(Repeatable Read)、串行化(Serializable)。四個級別逐漸增強,每個級別解決上個級別的一個問題。
2.1 讀未提交(Read Uncommitted)
另一個事務修改了數據,但尚未提交,而本事務中的SELECT會讀到這些未被提交的數據(臟讀)。
臟讀是指另一個事務修改了數據,但尚未提交,而本事務中的SELECT會讀到這些未被提交的數據。
2.2 讀已提交(Read Committed)
本事務讀取到的是最新的數據(其他事務提交后的)。問題是,在同一個事務里,前后兩次相同的SELECT會讀到不同的結果(不可重復讀)。
不可重復讀是指同一個事務執行過程中,另外一個事務提交了新數據,因此本事務先后兩次讀到的數據結果會不一致。
2.3 可重復讀(Repeatable Read)
在同一個事務里,SELECT的結果是事務開始時間點的狀態,同樣的SELECT操作讀到的結果會是一致的。但是,會有幻讀現象。
不可重復讀保證了同一個事務里,查詢的結果都是事務開始時的狀態(一致性)。但是,如果另一個事務同時提交了新數據,本事務再更新時,就會發現了這些新數據,貌似之前讀到的數據是幻覺,這就是幻讀。
2.4 串行化(Serializable)
所有事務只能一個接一個串行執行,不能并發。
3 隔離級別的選擇
事務隔離級別越高,越能保證數據的一致性,但對并發性能影響越大,一致性和高性能必須有所取舍或折中。
一般情況下,多數應用程序可以選擇將數據庫的隔離級別設置為讀已提交,這樣可以避免臟讀,也可以得到不錯的并發性能。盡管這個隔離級別會導致不可重復度、幻讀,但這種個別場合應用程序可以通過主動加鎖進行并發控制。