數據庫事務的四大特性和隔離級別

數據庫事務(Database Transaction) ,是指作爲單個邏輯工作單元執行的一系列操作,要麼全部執行,要麼全部都不執行。

一個邏輯工作單元要成爲事務,必須滿足事務的四大特性(ACID)。即原子性(Atomic)、一致性(Consistent)、隔離性(Insulation)和持久性(Duraction)。

原子性(Atomic):事務是一個完整的操作,事務的各個操作步驟是不可分的。即要麼都執行,要麼都不執行。

一致性(Consistent):事務執行的結果必須使數據庫從一個一致性狀態變到另一個一致性狀態

隔離性(Insulation):系統必須保證事務不受其他併發執行事務的影響。對任何一對事務T1和T2,在T1看來,T2要麼在T1開始之前已經結束,要麼在T1完成之後再開始執行。隔離通過併發控制機制實現。

持久性(Duraction):事務一旦提交到數據庫,它對數據庫的更新不再受後續操作或故障的影響。


如果我們不考慮事務的隔離性,將會造成以下情況發生:

1、髒讀

髒讀是指一個事務處理過程中讀取了另一個未提交事務的數據。

2、不可重複讀

不可重複讀是指在對數據庫中的某個數據,一個事務多次讀取卻返回不一樣的結果。這是由於在查詢的時候,被另一個事務修改提交了。

3、幻讀

幻讀是事務非獨立執行時發生的一種現象。例如事務T1對一個表中的所有行的某個數據從“Y”修改成“N”,此時事務T2正在向數據庫插入一條記錄,數值是“Y”。然後操作事務T1的用戶再次查看剛剛修改的數據後,會發現還是有一個數值爲“Y”的數據記錄。其實是事務T2添加的數據,這就產生了幻讀。


數據庫事務的隔離級別有4個,由低到高依次爲Read uncommittedRead committedRepeatable readSerializable,這四個級別可以逐個解決髒讀不可重複讀幻讀這幾類問題。


髒讀
不可重複讀
幻讀
Read uncommitted
Y
Y
Y

Read committed

N
Y
Y
Repeatable read
N
N
Y
Serializable
N
N
N


Read uncommitted(讀未提交)

例如:A向B轉賬5000元,但是A剛開始轉了8000給B賬戶,但是還沒有提交事務。然後現在B去賬戶裏面查多了8000,A後面發現多轉了,於是就重新回滾事務轉了5000給B賬號,等B下次再去查看的時候發現是5000,這就產生了髒讀。

Read committed(讀提交)

singo拿着工資卡去消費,系統讀取到卡里確實有2000元,而此時她的老婆也正好在網上轉賬,把singo工資卡的2000元轉到另一賬戶,並在singo之前提交了事務,當singo扣款時,系統檢查到singo的工資卡已經沒有錢,扣款失敗,singo十分納悶,明明卡里有錢,爲何......

出現上述情況,即我們所說的不可重複讀,兩個併發的事務,“事務A:singo消費”、“事務B:singo的老婆網上轉賬”,事務A事先讀取了數據,事務B緊接了更新了數據,並提交了事務,而事務A再次讀取該數據時,數據已經發生了改變。

當隔離級別設置爲Read committed時,避免了髒讀,但是可能會造成不可重複讀。

Repeatable read (重複讀)

當隔離級別設置爲Repeatable read時,可以避免不可重複讀。當singo拿着工資卡去消費時,一旦系統開始讀取工資卡信息(即事務開始),singo的老婆就不可能對該記錄進行修改,也就是singo的老婆不能在此時轉賬。

雖然Repeatable read避免了不可重複讀,但還有可能出現幻讀。

singo的老婆工作在銀行部門,她時常通過銀行內部系統查看singo的信用卡消費記錄。有一天,她正在查詢到singo當月信用卡的總消費金額(select sum(amount) from transaction where month = 本月)爲80元,而singo此時正好在外面胡吃海塞後在收銀臺買單,消費1000元,即新增了一條1000元的消費記錄(insert transaction ... ),並提交了事務,隨後singo的老婆將singo當月信用卡消費的明細打印到A4紙上,卻發現消費總額爲1080元,singo的老婆很詫異,以爲出現了幻覺,幻讀就這樣產生了。

Serializable (序列化)

Serializable是最高的事務隔離級別,同時代價也花費最高,性能很低,一般很少使用,在該級別下,事務順序執行,不僅可以避免髒讀、不可重複讀,還避免了幻像讀。






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