1. 程式人生 > >資料庫的髒讀、不可重複讀、幻讀以及四種隔離級別

資料庫的髒讀、不可重複讀、幻讀以及四種隔離級別

資料庫的髒讀、不可重複讀和幻讀

髒讀:也就是當資料庫的一個事務A正在使用一個數據但還沒有提交,另外一個事務B也訪問到了這個資料,還使用了這個資料,這就會導致事務B使用了事務A沒有提交之前的資料。
不可重複讀:在一個事務A中多次操作一個數據,在這兩次或多次訪問這個資料的中間,事務B也操作此資料,並使其值發生了改變,這就導致同一個事務A在兩次操作這個資料的時候值不一樣,這就是不可重複讀。

幻讀:是指事務不獨立執行產生的一種現象。事務A讀取與搜尋條件相匹配的若干行。事務B以插入或刪除行等方式來修改事務A的結果集,然後再提交。這樣就會導致當A本來執行的結果包含B執行的結果,這兩個本來是不相關的,對於A來說就相當於產生了“幻覺”。

資料庫的四種隔離級別(併發事務):

(一)可讀取未提交(Read uncommitted)

寫事務阻止其他寫事務,避免了更新遺失。但是沒有阻止其他讀事務。 
存在的問題:髒讀。即讀取到不正確的資料,因為另一個事務可能還沒提交最終資料,這個讀事務就讀取了中途的資料,這個資料可能是不正確的。 
解決辦法就是下面的“可讀取確認”。

(二)可讀已提交(Read committed)

Sql Server , Oracle的預設隔離級別
寫事務會阻止其他讀寫事務。讀事務不會阻止其他任何事務。 
存在的問題:不可重複讀。即在一次事務之間,進行了兩次讀取,但是結果不一樣,可能第一次id為1的人叫“李三”,第二次讀id為1的人就叫了“李四”。因為讀取操作不會阻止其他事務。 
解決辦法就是下面的“可重複讀”。

(三)可重複讀(Repeatable read)

MySQL的預設隔離級別
讀事務會阻止其他寫事務,但是不會阻止其他讀事務。 
存在的問題:幻讀。可重複讀阻止的寫事務包括update和delete(只給存在的表加上了鎖),但是不包括insert(新行不存在,所以沒有辦法加鎖),所以一個事務第一次讀取可能讀取到了10條記錄,但是第二次可能讀取到11條,這就是幻讀。
解決辦法就是下面的“序列化”。

(四)序列化(Serializable)

可避免幻讀。讀加共享鎖,寫加排他鎖。這樣讀取事務可以併發,但是讀寫,寫寫事務之間都是互斥的,基本上就是一個個執行事務,所以叫序列化。