事務與隔離級別

事務的基本特徵 ACID

  • Atomic(原子性):事務中全部的操做是一個總體單元,這個單元中的操做要麼所有成功,要麼所有失敗,不會出現部分失敗、部分紅功的場景;
  • Consistency(一致性):事務在完成時,必須使全部的數據都保持一致的狀態(約束 a + b = 10,事務結束後 a + b = 10 仍然成立);
  • Isolation(隔離性):各個事務在必定程度上感受不到其餘事務的存在(體如今不一樣的隔離級別上);
  • Durability(持久性):事務提交後,全部的數據都會永久寫入到磁盤。

事務的隔離級別

數據庫標準提出了 4 類隔離級別,在不一樣程度上壓制更新丟失。數據庫

  1. 讀未提交
  2. 讀已提交
  3. 可重複讀
  4. 串行化

讀未提交

讀未提交(read uncommitted) 是最低的隔離級別,容許一個事務讀取另外一個事務沒有提交的數據。適合對於數據一致性沒有要求的場景。它存在髒讀的現象,以下表:性能

時刻 事務 1 事務 2 說明
T1 讀取庫存爲 2 庫存爲 2
T2 庫存 - 1 庫存爲 1
T3 庫存 - 1 庫存爲 0(讀取到事務 1 沒有提交的數據)
T4 提交事務 庫存保存爲 0
T5 回滾 庫存爲 0(第一類丟失更新已經克服)

第一類丟失更新:一個事務回滾,另外一個事務提交,回滾覆蓋了提交的數據。目前的數據庫都克服了第一類丟失更新。事務

讀已提交

讀已提交(read committed) 是指一個事務只能讀取另外一個事務已提交的數據,不能讀取未提交的數據。ci

時刻 事務 1 事務 2 說明
T1 讀取庫存爲 2 庫存爲 2
T2 庫存 - 1 事務 1 中庫存爲 1
T3 庫存 - 1 事務 2 中庫存爲 1(事務 1 未提交)
T4 提交 庫存保存爲 1
T5 回滾事務 庫存爲 1 (第一類丟失更新已經克服)

上表中的操做結果最終正確。可是讀已提交會產生不可重複讀it

時刻 事務 1 事務 2 說明
T1 讀取庫存爲 1 庫存爲 1
T2 庫存 - 1 事務 1 中庫存爲 0
T3 讀取庫存爲 1 事務 2 認爲能夠扣減(事務 1 未提交)
T4 提交 庫存保存爲 0
T5 庫存 - 1 失敗,此時庫存爲 0

這裏事務 2 在事務 1 提交以前認爲能夠扣減,然後來事務 2 扣減時發現庫存已經爲 0 沒法扣減,這樣的現象稱爲不可重複讀,這就是讀已提交的一個不足。io

可重複讀

可重複讀(read repeatable) 的目標是克服讀已提交中出現的不可重複讀的現象。table

時刻 事務 1 事務 2 說明
T1 讀取庫存爲 1 庫存爲 1
T2 庫存 - 1 事務 1 中庫存爲 0
T3 讀取庫存 事務 2 不能讀取,等待事務 1 提交
T4 提交 庫存保存爲 0
T5 讀取庫存 庫存爲 0,沒法扣減

當事務 2 讀取事務 1 事先讀取的數據時,會被阻塞,直到事務 1 提交後事務 2 才能讀取,讀已提交中出現的不可重複讀現象消失了。可是可重複讀會出現幻讀:class

時刻 事務 1 事務 2 說明
T1 查詢庫存 100 庫存 100,10 個訂單
T2 查詢訂單爲 10
T3 庫存 - 1
T4 插入訂單
T5 提交 庫存 99,11 個訂單
T6 打印訂單,11 單 事務 2 中多了一條記錄,與以前查詢的不一致

上表出現的就是幻讀現象,幻讀不是針對一條數據庫記錄而言,而是多條記錄,上表中訂單是多條記錄統計出來的,它會產生幻讀。統計

串行化

串行化(serializable) 是數據庫最高的隔離級別,全部的事務都按順序執行。它能夠克服前面的隔離級別中出現的各類問題,可以徹底保證數據的一致性。總結

總結

隔離級別 髒讀 不可重複讀 幻讀
讀未提交
讀已提交 ×
可重複讀 × ×
串行化 × × ×

不一樣的隔離級別可以在不一樣程度上壓制丟失更新,使用更高的隔離級別可以更好地保證數據的一致性,可是也要付出性能的代價。隔離級別越高,性能越是直線地降低。

相關文章
相關標籤/搜索