事物級別,不可重複讀和幻讀的區別
事物級別,不可重複讀和幻讀的區別
什麼是事務
資料庫事務(簡稱:事務)是資料庫管理系統執行過程中的一個邏輯單位,由一個有限的資料庫操作序列構成。—— 維基百科
為什麼需要隔離性?
髒讀
髒讀(dirty read),簡單來說,就是一個事務在處理過程中讀取了另外一個事務未提交的資料。
舉例
時間點 | 事務A | 事務B |
---|---|---|
1 | 開啟事務A | |
2 | 開啟事務B | |
3 | 查詢餘額為100 | |
4 | 餘額增加至150 | |
5 | 查詢餘額為150 |
比如,你給小編讚賞 1 分錢,整個事務需要兩個步驟: ①給小編賬號加一分錢,這時小編看到了,覺得很欣慰; ②你的賬號減一分錢;
但是,若該事務未提交成功,最終所有操作都會回滾,小編看到的一分錢也只是鏡花水月。
可重複讀
不可重複讀(non-repeatable read),是指一個事務範圍內,多次查詢某個資料,卻得到不同的結果。
在第一個事務中的兩次讀取資料之間,由於第二個事務的修改,第一個事務兩次讀到的資料可能就是不一樣的。
舉例
時間點 | 事務A | 事務B |
---|---|---|
1 | 開啟事務A | |
2 | 開啟事務B | |
3 | 查詢餘額為100 | |
4 | 餘額增加至150 | |
5 | 查詢餘額為100 | |
6 | 提交事務 | |
7 | 查詢餘額為150 |
接著上一個例子,假設你真給小編打賞了一分錢,小編樂得屁顛屁顛地去準備提現,一查,發現真多了一分錢。
在這同時,在我還沒有提現成功之前,小編的老婆已經提前將這一分錢支走了,小編此時再次查賬,發現一分錢也沒了。
髒讀和不可重複讀有點懵逼?
二者的區別是,髒讀是某一事務讀取了另外一個事務未提交的資料,不可重複讀是讀取了其他事務提交的資料。
其實,有些情況下,不可重複讀不是問題,比如,小編提現期間,一分錢被老婆支走了,這不是問題!
而髒讀,是可以通過設定隔離級別避免的。
幻讀
幻讀(phantom read),是事務非獨立執行時發生的一種現象。
例如事務 T1 對一個表中所有的行的某個資料項做了從“1”修改為“2”的操作,這時事務 T2 又對這個表中插入了一行資料項為“1”的資料,並且提交給資料庫。
而操作事務 T1 的使用者如果再檢視剛剛修改的資料,會發現資料怎麼還是 1?其實這行是從事務 T2 中新增的,就好像產生幻覺一樣,這就是發生了幻讀。
舉例
時間點 | 事務A | 事務B |
---|---|---|
1 | 開啟事務A | |
2 | 開啟事務B | |
3 | 查詢id<3的所有記錄,共3條 | |
4 | 插入一條記錄id=2 | |
5 | 提交事務 | |
6 | 查詢id<3的所有記錄,共4條 |
幻讀和不可重複讀都是讀取了另一條已經提交的事務(這點就髒讀不同),所不同的是不可重複讀查詢的都是同一個資料項,而幻讀針對的是一批資料整體(比如資料的個數)。
事務的隔離級別
為了解決上面可能出現的問題,我們就需要設定隔離級別,也就是事務之間按照什麼規則進行隔離,將事務隔離到什麼程度。
首先,需要明白一點,隔離程度越強,事務的執行效率越低。
ANSI/ISO SQL 定義了 4 種標準隔離級別:
① Serializable(序列化):花費最高代價但最可靠的事務隔離級別。
“寫”會加“寫鎖”,“讀”會加“讀鎖”。當出現讀寫鎖衝突的時候,後訪問的事務必須等前一個事務執行完成,才能繼續執行。
事務 100% 隔離,可避免髒讀、不可重複讀、幻讀的發生。
② Repeatable read(可重複讀,預設級別):多次讀取同一範圍的資料會返回第一次查詢的快照,即使其他事務對該資料做了更新修改。事務在執行期間看到的資料前後必須是一致的。
但如果這個事務在讀取某個範圍內的記錄時,其他事務又在該範圍內插入了新的記錄,當之前的事務再次讀取該範圍的記錄時,會產生幻行,這就是幻讀。
可避免髒讀、不可重複讀的發生。但是可能會出現幻讀。
③ Read committed (讀已提交):保證一個事物提交後才能被另外一個事務讀取。另外一個事務不能讀取該事物未提交的資料。
可避免髒讀的發生,但是可能會造成不可重複讀。
大多數資料庫的預設級別就是 Read committed,比如 Sql Server , Oracle。
④ Read uncommitted (讀未提交):最低的事務隔離級別,一個事務還沒提交時,它做的變更就能被別的事務看到。
任何情況都無法保證。
再次總結
讀未提交:別人改資料的事務尚未提交,我在我的事務中也能讀到。 讀已提交:別人改資料的事務已經提交,我在我的事務中才能讀到。 可重複讀:別人改資料的事務已經提交,我在我的事務中也不去讀。 序列:我的事務尚未提交,別人就別想改資料。
這 4 種隔離級別,並行效能依次降低,安全性依次提高。