1. 程式人生 > >MySQL InnoDB :事務隔離隔離級別以及對應的問題

MySQL InnoDB :事務隔離隔離級別以及對應的問題

通過鎖機制可以實現事務的隔離性要求,使得事務可以併發地工作。但是鎖的使用也會帶來幾種問題:髒讀,不可重複讀,幻讀, 丟失更新。

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才可以避免