淘寶海量資料庫之三:事務的ACID(轉)

物理狂人發表於2012-02-29

每個事務使得資料庫從一個一致的永久狀態原子地轉移到一個新的一致的永久狀態,可以說,事務的ACID(the transactional properties of Atomicity, Consistency, Isolation and Durability)屬性是資料庫事務的靈魂

  · 原子性

  事務的原子性首先體現在事務對資料的修改,即要麼全都執行,要麼全都不執行,例如,從銀行賬戶A轉一筆款項a到賬戶B,結果必須是從A的賬戶上扣除款項a並且在B的賬戶上增加款項a,不能只是其中一個賬戶的修改。但是,事務的原子性並不總是能夠保證修改一定完成了或者一定沒有進行,例如在ATM機器上進行上述轉賬,轉賬指令提交後通訊中斷或者資料庫主機異常了,那麼轉賬可能完成了也可能沒有進行:如果通訊中斷髮生前資料庫主機完整接收到了轉賬指令且後續執行也正常,那麼轉賬成功完成了;如果轉賬指令沒有到達資料庫主機或者雖然到達但後續執行異常(例如寫commit log失敗或者賬戶餘額不足),那麼轉賬就沒有進行。要確定轉賬是否成功,需要待通訊恢復或者資料庫主機恢復後查詢賬戶交易歷史或餘額。事務的原子性也體現在事務對資料的讀取上,例如一個事務對同一資料項的多次讀取的結果一定是相同的。

  · 一致性

  事務需要保持資料庫資料的正確性、完整性和一致性,有些時候這種一致性由資料庫的內部規則保證,例如資料的型別必須正確,資料值必須在規定的範圍內,等等;另外一些時候這種一致性由應用保證的,例如一般情況下銀行賬務餘額不能是負數,信用卡消費不能超過該卡的信用額度等。

  · 隔離性

  許多時候資料庫在併發執行多個事務,每個事務可能需要對多個表項進行修改和查詢,與此同時,更多的查詢請求可能也在執行中。資料庫需要保證每一個事務在它的修改全部完成之前,對其他的事務是不可見的,換句話說,不能讓其他事務看到該事務的中間狀態,例如,從銀行賬戶A轉一筆款項a到賬戶B,不能讓其他事務(例如賬戶查詢)看到A賬戶已經扣除款項a但B賬戶卻還沒有增加款項a的狀態。

  · 永續性

  事務完成後,它對於資料庫的影響是永久性的,即使系統出現各種異常也是如此。

  出於效能考慮,許多資料庫允許使用者選擇犧牲隔離屬性來換取併發度,從而獲得效能的提升。SQL定義了4種隔離級別:

  ·Read uncommitted (RU):讀取未提交的資料,即其他事務已經修改但還未commit的資料,這是最低的隔離級別;

  ·Read committed (RC):在一個事務中,對同一個項,前面的讀取跟後面的讀取結果可能不一樣,例如第一次讀取時另一個事務的修改還沒有提交,第二次讀取時已經提交了;

  ·Repeatable read (RR):可重複讀取,在一個事務中,對同一個項,前面的讀取跟後面的讀取結果一樣;

  ·Serializable (S):可序列化,即資料庫的事務是可序列化執行的,就像一個事務執行的時候沒有別的事務同時在執行,這是最高的隔離級別;

  隔離級別的降低可能導致讀到髒資料或者事務執行異常,例如:

  ·Lost update (LU):兩個事務同時修改一個資料項,但後一個事務中途失敗退出,則對資料項的兩個修改可能都丟失;

  ·Dirty Reads (DR):一個事務讀取某資料項,但另一個事務更新了此資料項卻沒有提交,這樣所有的操作可能都得回滾;

  ·Non-repeatable Reads (NRR):一個事務對同一資料項的多次讀取可能得到不同的結果;

  ·Second lost updates problem (SLU):無法重複讀取的特例:兩個併發事務同時讀取和修改同一資料項,則後面的修改可能使得前面的修改失效;

  ·Phantom Reads (PR):也稱為幻讀,例如在事務執行過程中,由於前面的查詢和後面的查詢的期間有另外一個事務插入資料,後面的查詢結果出現了前面查詢結果中未出現的資料。

  隔離級別與讀寫異常(不一致)的關係如下:

 

LU

DR

NRR

SLU

PR

RU

Y

Y

Y

Y

Y

RC

N

N

Y

Y

Y

RR

N

N

N

N

Y

S

N

N

N

N

 

N

  容易發現,在最高隔離級別serializable下,資料不會出現讀寫的不一致。

  不同的資料庫支援的隔離級別不盡相同,例如oracle只支援read committed和serializable兩個級別,MySQL支援全部四個級別。

  OceanBase的事務實現與經典關聯式資料庫有所不同,其讀事務基本是分散式併發執行的,寫事務目前是集中式序列執行的,即serializable,且任何一個寫事務在commit之前對其他讀寫事務都是不可見的,因此OceanBase是強一致的。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24104518/viewspace-717403/,如需轉載,請註明出處,否則將追究法律責任。

相關文章