資料庫中隔離性的四種級別詳解與例子-爭取一文全懂

內容有侵權或者不能公開的,請聯繫我,微信號:GeorgeChongVIP 或 掃描知乎頭像

最近在看分散式資料庫中的數據一致性,看到了事務的隔離性,過年在家寫論文,順便總結一下,有問題,請隨意拍磚,學生黨。

事務的隔離性一般分為4個級別:

1. Read Uncommitted 未授權讀取,實質上該級別允許讀取未提交的數據,就是允許臟讀。如果一個事務A讀取了一條記錄 r,並修改了該記錄,事務A尚未提交時,事務B讀取了r,如果事務A最後回滾了(因某種原因),那麼事務B讀了一條無效的記錄。[1]給的例子,如果事務A對某一個值進行了 加1 操作 10 次,事務B能讀取其中的中間值 2,3,4... ,這一系列中間值的讀取就是未授權讀取。

2. Read Committed 授權讀取,也叫只讀已提交數據,不允許臟讀了。如果事務A對讀取了一條記錄 r1,並修改了該記錄為 r2,事務A尚未提交時,事務B讀取該記錄,依然是原來的 r1,當事務A committed以後,事務B才能讀取事務A修改後的值 r2,這就是授權讀取,不會讀中間數據,只讀最終提交的數據。

但是,這有個問題,不可重複讀問題(在一個事務範圍內,執行2個相同的查詢,查詢的結果不同,因為有其他事務update了數據)。事務A事先讀取了數據,事務B緊接了更新了數據,並提交了事務,而事務A再次讀取該數據時,數據已經發生了改變 [2],造成了不可重複讀。

3. Repeatable Read 可重複讀,該隔離界別是多次讀取同一條記錄時,讀取結果相同。這是禁止了不可重複讀,實質上,當事務A讀取記錄r1時,不允許其他事務修改 r1,如果修改,需要等待事務A處理結束。說個額外有趣的,當事務A在修改數據時,發生了查詢怎麼辦?實際應用中,是給數據和查詢加了一個SCN (System change number),簡單的說,為每一個查詢添加一個時間戳,然後對比記錄的時間戳,詳見 [3]。

但是還是有問題,無法解決幻讀問題,比如事務A 將 T表 中所有工資不到 10000元 的員工的工資改為10000元,在事務A執行結束尚未提交時,事務B又插入了一條(或刪除操作)工資不滿10000元的員工記錄,然後再提交事務A,事務B。事務A好像發生了幻覺,沒有操作成功一樣,這是因為「可重複讀」鎖定的是,已經讀取的記錄,而不是鎖定整張表(或者超出讀取範圍的數據),可重複讀限制了事務本身涉及數據的update行為,但是無法限制事務自身以外的數據。我們可以使用表鎖或者範圍鎖。

4. Serializable 串列化,這是最嚴苛的事務隔離級別。將所有事務串列化執行,簡單暴力,直覺低效(但是也看場合)。

實際應用中,更多的是採用樂觀鎖,去保證數據的一致性,提高效率。最後說一下,樂觀鎖和悲觀鎖不是「鎖」,以後補充。

1. 《從Paxos到ZooKeeper》倪超

2. 讀提交和可重複讀區別 - 盧彩方的專欄 - 博客頻道 - CSDN.NET

3. oracle保證讀一致性原理 - Oracle資料庫欄目 - 紅黑聯盟

推薦閱讀:

聊聊分散式
Spring整合Quartz分散式調度
分散式事務提交協議: 2PC/3PC
分散式事務解決方案與適用場景分析
分散式系統數據層設計模式

TAG:事務並發 | 一致性 | 分散式事務 |