資料庫隔離級別

2022-05-08 21:48:08 字數 1844 閱讀 3859

公司發工資了,領導把5000元打到singo的賬號上,但是該事務並未提交,而singo正好去檢視賬戶,發現工資已經到賬,是5000元整,非常高 興。可是不幸的是,領導發現發給singo的工資金額不對,是2000元,於是迅速回滾了事務,修改金額後,將事務提交,最後singo實際的工資只有 2000元,singo空歡喜一場。

出現上述情況,即我們所說的髒讀 ,兩個併發的事務,「事務a:領導給singo發工資」、「事務b:singo查詢工資賬戶」,事務b讀取了事務a尚未提交的資料。

當隔離級別設定為read uncommitted 時,就可能出現髒讀,如何避免髒讀,請看下乙個隔離級別。

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

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

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

大多數資料庫的預設級別就是read committed,比如sql server , oracle。如何解決不可重複讀這一問題,請看下乙個隔離級別。

當隔離級別設定為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的老婆很詫異,以為出 現了幻覺,幻讀就這樣產生了。

注:兩次相同的查詢,返回的行數不同即為「幻讀」,而不是相同的行某個欄位的變化;

在可重複讀中,該sql第一次讀取到資料後,就將這些資料加鎖(悲觀鎖),其它事務無法修改這些資料,就可以實現可重複讀了。但這種方法卻無法鎖住insert的資料,所以當事務a先前讀取了資料,或者修改了全部資料,事務b還是可以insert資料提交,這時事務a就會發現莫名其妙多了一條之前沒有的資料,這就是幻讀,不能通過行鎖來避免。需要serializable隔離級別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼做可以有效的避免幻讀、不可重複讀、髒讀等問題,但會極大的降低資料庫的併發能力。

但是mysql、oracle、postgresql等成熟的資料庫,出於效能考慮,都是使用了以樂觀鎖為理論基礎的mvcc(多版本併發控制)來實現。

注:mysql的預設隔離級別就是repeatable read。

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

**:

資料庫隔離級別

read uncommited 讀未提交 最低級別,可讀取未提交事物的資料,這會導致髒讀,比如 某時刻會話a修改了乙個資料,但還未提交,此時會話b,讀取了該資料,這是,會話a回滾了事物,這就導致資料出現了不一致狀態,這就是髒讀 read commited 提交讀 避免了髒讀,但會導致不可重複讀,例如...

資料庫隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀 不可重複讀 幻讀read uncommitted re...

資料庫隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...