[數據庫]事務和隔離級別

一 、事務

1 事務的定義

事務(Transaction)是併發控制的基本單位。事務是構成單一邏輯工作單元的操作集合,要麼完整的執行,要麼完全不執行。不論任何情況,DBS必須保證事務能正確完整的執行。

##2 事務的特性
● Atomic(原子性):事務中包含的操作被看做一個邏輯單元,這個邏輯單元中的操作要麼全部成功,要麼全部失敗。

● Consistency(一致性):只有合法的數據可以被寫入數據庫,否則事務應該將其回滾到最初狀態。

● Isolation(隔離性):事務允許多個用戶對同一個數據進行併發訪問,而不破壞數據的正確性和完整性。同時,並行事務的修改必須與其他並行事務的修改相互獨立。

● Durability(持久性):事務結束後,事務處理的結果必須能夠得到固化。

2 併發帶來的問題及解決方案

注:以下內容僅代表筆者自己的觀點,不具備權威性,請理性參考,歡迎指正

1 髒讀

現象:髒讀是指在一個事務處理過程裏讀取了另一個未提交的事務中的數據。
  產生原因(之一):兩個事務,事務A讀的時候沒有加共享鎖,事務B插入的時候加了排它鎖(加沒加不重要),所以在事務A讀記錄的時候,事務B可以進行插入,所以A讀到了B插入的還未提交的數據,但是稍後B回滾了,所以A讀到了髒數據,這裏的髒數據是指,B插入但是稍後又回滾的數據。
  解決辦法(之一):讀取數據時加共享鎖。

2 不可重複讀

現象:同一個事務,查詢同一條記錄,前後兩次的查詢結果不同。
  產生的原因(之一):兩個事務A和B,A事務兩次讀取同一條記錄,每次讀取記錄時加共享鎖,B在A兩次讀取之間修改了A要讀取的記錄,修改時加了排它鎖,由於A第一次讀取完記錄釋放了共享鎖,所以B修改了該條記錄,導致不可重複讀。
  解決辦法(之一):A事務讀取數據時加共享鎖,直到A事務結束時才釋放該共享鎖,這樣A兩次讀取相同記錄的間隙,B沒有機會修改A要讀取的記錄。
  在某些情況下,不可重複讀並不是問題,比如我們多次查詢某個數據當然以最後查詢得到的結果爲主。但在另一些情況下就有可能發生問題,例如對於同一個數據A和B依次查詢就可能不同,A和B就可能打起來了……

3 幻讀(虛讀)

現象:同一個事務,用相同的查詢條件,前後兩次查詢得到的結果集不相同,比如說第一次查到了3條,但是第二次查詢到了4條。
  舉例:假如tab_A的主鍵是id,SQL:select * from tab_A where id > 0;如果事務A第一次查詢該表該表中滿足該條件的記錄只有3條,id分別爲1,2,3,但是在A第二次查詢之前,事務B插入一條id = 4的記錄,就會導致A第二次再用相同的SQL會查到4條記錄。
  產生的原因(之一):A對於第一次讀取的三條記錄加了共享鎖,但是僅對查詢出來的滿足where條件的記錄加了共享鎖,還是允許B插入滿足查詢條件的記錄,就導致了幻讀。
  解決辦法(之一):不允許B在A兩次查詢之間想要插入滿足A查詢條件的記錄即可解決幻讀問題。

二 隔離級別

這裏寫圖片描述

1 可讀未提交(Read uncommitted)

寫事務阻止其他寫事務,避免了更新遺失。但是沒有阻止其他讀事務。
存在的問題:髒讀。
解決辦法就是下面的“Read committed”。

2 可讀已提交(Read committed)

寫事務會阻止其他讀寫事務。讀事務不會阻止其他任何事務。
存在的問題:不可重複讀。
解決辦法就是下面的“可重複讀”。

3 可重複讀(Repeatable read)

讀事務會阻止其他寫事務,但是不會阻止其他讀事務。
存在的問題:幻讀。
解決辦法就是下面的“串行化”。

4 串行化(Serializable)

讀對滿足條件的記錄加共享鎖且不允許插入滿足查詢條件的記錄,直到事務結束才釋放鎖,寫加排他鎖。這樣讀取事務可以併發,但是讀寫,寫寫事務之間都是互斥的,基本上就是一個個執行事務,所以叫串行化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章