您好,登錄后才能下訂單哦!
數據庫事務(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 uncommitted、Read committed、Repeatable read、Serializable,這四個級別可以逐個解決臟讀、不可重復讀、幻讀這幾類問題。
臟讀 | 不可重復讀 | 幻讀 | |
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時,可以避免不可重復讀。當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是最高的事務隔離級別,同時代價也花費最高,性能很低,一般很少使用,在該級別下,事務順序執行,不僅可以避免臟讀、不可重復讀,還避免了幻像讀。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。