MySQL InnoDB :事務隔離隔離級別以及對應的問題
阿新 • • 發佈:2019-01-24
通過鎖機制可以實現事務的隔離性要求,使得事務可以併發地工作。但是鎖的使用也會帶來幾種問題:髒讀,不可重複讀,幻讀, 丟失更新。
ANSI SQL隔離級別
隔離級別 | 髒讀 | 不可重讀 | 幻讀 | 加鎖讀 |
READ-UNCOMMITTED | YES | YES | YES | NO |
RED-COMMITTED | NO | YES | YES | NO |
REPEATABLE-READ | NO | NO | YES | NO |
SERIALIZABLE | NO | NO | NO | YES |
1, 髒讀 :事務A會讀取另外一個事務B尚未提交的資料(Read-Uncommitted)
違反事務的隔離性(isolation)要求
髒資料:事務對緩衝池中的行記錄已經修改,但是還沒有被提交(uncommitted)。
這種情況會在tx_isolation=READ-UNCOMMITTED的情況下出現。
只要tx_isolation=READ-COMMITTED,就可以避免髒讀。
事務A | 事務B |
begin; | |
begin; | |
select * from phantom where a=1; (1,1) | |
update phantom set b=100 where a=1; | |
select * from phantom where a=12;(1,100) | |
commit; | |
commit; |
2, 不可重複讀 : 事務A讀取某一行資料 r = r0, 同時另一個事務B修改 r = r1 ,並且提交,導致事務A讀取的資料 r 前後不一致。
違反事務的一致性(consistent)要求
這種情況會在tx_isolation=READ-COMMITTED的情況下出現。
只要tx_isolation=REPEATABLE-READ就可以避免
事務A | 事務B |
begin; | |
begin; | |
select * from phantom where a=1; (1,1) | |
update phantom set b=100 where a=1; | |
commit; | |
select * from phantom where a=12;(1,100) | |
commit; |
3,幻讀Phantom Read
當事務A讀取在某個範圍內的記錄時,另一個事務B又在該範圍內插入了新的資料,當A再次讀該範圍內的資料時產生了幻行。
這種情況會在tx_isolation=REPEATABLE-READ的時候產生,要避免的話需要設定tx_isolation=Serializable
事務A | 事務B |
begin; | |
begin; | |
select * from phantom; (1,1) | |
insert into phantom values(1,2); | |
commit; | |
select * from phantom;(1,1)(1,2) | |
commit; |
4,丟失更新
兩個事務都對某個資料進行更新操作,但是其中一個被覆蓋。這種情況會在tx_isolation=REPEATABLE-READ的情況下出現。
這時候需要設定為tx_isolation=Serializable才可以避免