臟讀(Dirty Read)
當一個事務對數據進行了修改,但是未提交,這時另外一個事務讀取到這個數據,稱之為臟讀。
臟數據:未提交的數據。
臟讀:一個事務讀到另一個事務的未提交數據。
時間點 | 事務A | 事務B |
---|---|---|
1 | 開啟事務A | |
2 | 開啟事務B | |
3 | 查詢余額為100 | |
4 | 余額增加至150(未提交) | |
5 | 查詢余額為150 | |
6 | 事務回滾 |
不可重復讀(Unrepeatableread)
不可重復讀是指在一個事務內多次讀取同一數據集合。在這個事務還沒有結束時,另一個事務也訪問了該同一數據集合,並做了一些DML操作。那么第一個事務中的兩次讀數據之間,由於第二個事務的修改導致第一個事務兩次讀取的數據可能不太一樣,如果讀到不一樣的數據,由於這個不一樣的數據是已提交的數據,導致不可重復讀原始數據,所以稱為不可重復讀。
不可重復讀:一個事務讀到另一個事務已提交的數據導致不可重復讀原始數據。
時間點 | 事務A | 事務B |
---|---|---|
1 | 開啟事務A | |
2 | 開啟事務B | |
3 | 查詢余額為100 | |
4 | 余額增加至150(未提交) | |
5 | 查詢余額為100 | |
6 | 提交事務 | |
7 | 查詢余額為150 |
幻讀(Phantom read)
幻讀與不可重復讀類似。它發生在一個事務(T1)讀取了幾行數據,接着另一個並發事務(T2)插入了一些數據時。在隨后的查詢中,第一個事物(T1)就會發現多了一些原本不存在的記錄,就好像發生了幻覺一樣,所以稱之為幻讀。
時間點 | 事務A | 事務B |
---|---|---|
1 | 開啟事務A | |
2 | 開啟事務B | |
3 | 查詢id<3的所有記錄,共3條 | |
4 | 插入一條記錄id=2 | |
5 | 提交事務 | |
6 | ||
7 | 查詢id<3的所有記錄,共4條 |
區別
臟讀和不可重復讀的區別:
臟讀讀的是未提交數據,不可重復讀讀的是已提交數據。
不可重復讀和幻讀的區別:
不可重復讀的重點是修改(UPDATE)數據,幻讀的重點在於新增(INSERT)或者刪除(DELETE)記錄。
解決不可重復讀的問題只需要鎖住滿足條件的行,解決幻讀需要鎖表。