天天看點

【資料庫】——事務ACID及隔離級别

(一)概念

事務(Transaction)是并發控制的基本機關。所謂的事務,它是一個操作序列,這些操作要麼都執行,要麼都不執行,它是一個不可分割的工作機關。例如,銀行轉賬工作:從一個賬号扣款并使另一個賬号增款,這兩個操作要麼都執行,要麼都不執行。

(二)ACID特性

如果一個資料庫支援事務操作,那麼他具有以下四種特性:

⑴ 原子性(Atomicity)

  原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗復原,這和前面兩篇部落格介紹事務的功能是一樣的概念,是以事務的操作如果成功就必須要完全應用到資料庫,如果操作失敗則不能對資料庫有任何影響。

⑵ 一緻性(Consistency)

  一緻性是指事務必須使資料庫從一個一緻性狀态變換到另一個一緻性狀态,也就是說一個事務執行之前和執行之後都必須處于一緻性狀态。

  拿轉賬來說,假設使用者A和使用者B兩者的錢加起來一共是5000,那麼不管A和B之間如何轉賬,轉幾次賬,事務結束後兩個使用者的錢相加起來應該還得是5000,這就是事務的一緻性。

⑶ 隔離性(Isolation)

  隔離性是當多個使用者并發通路資料庫時,比如操作同一張表時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作所幹擾,多個并發事務之間要互相隔離。

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

  關于事務的隔離性資料庫提供了多種隔離級别,稍後會介紹到。

⑷ 持久性(Durability)

  持久性是指一個事務一旦被送出了,那麼對資料庫中的資料的改變就是永久性的,即便是在資料庫系統遇到故障的情況下也不會丢失送出事務的操作。

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

首先需要解釋一下幾個跟隔離性相關的概念定義:

(1)髒讀:指事務讀到髒資料,所謂髒資料,指的是不正确的資料,例如事務執行過程中修改了某記錄,然後復原,如果其他事務讀到了該記錄的中間修改值,則為髒讀。

(2)不可重複讀:事務在執行過程中,多次對同一個已經存在的記錄進行讀取,各次讀取的值不同。讀送出隔離級别存在不可重複讀的問題,事務1、2并發執行,事務2首先讀取記錄1,然後事務1修改記錄1并送出,事務2繼續讀取記錄1,則事務2兩次讀取到的值不同。

(3)幻讀:幻讀是指使用某個條件讀取一批記錄時,可能讀到的記錄數不同。幻讀與髒讀、不可重複讀的差別在于,髒讀、不可重複讀都是針對某個确定的已經存在的記錄出現的值不要求(讀到髒資料或多次讀的值不同),而幻讀則是多次使用同一個條件查詢一批記錄,多次讀到的記錄數不同,也就是說,髒讀、不可重複讀是由于多個事務并行執行update引起的,而幻讀則是由于多個事務并行執行insert引起的(并發delete引起的問題看起來算哪個都行……)

(三)隔離級别

四個隔離級别為:

(1)Read Uncommited:讀未送出,其含義為多個并發事務,任何一個事務可以讀到其他事務尚未送出的修改:

存在髒讀、不可重複讀、幻讀可能性。

(2)Read Commited:讀已送出,含義為多個并發事務,任何一個事務隻可以讀到其他事務已經送出的修改:

解決髒讀,存在不可重複讀、幻讀可能性。

(3)Repeatable Read:可重複讀,含義為多個事務并發執行時,任何一個事務反複讀取已存在的記錄,每次讀到的值都是相同的

解決髒讀、不可重複讀,存在幻讀可能性。

(4)Serializable:串行化,含義為所有事務串行執行,是以不存在事務并發執行的情況。

解決髒讀、不可重複讀、幻讀。