下面不同的隔離級別均已下面這張表為例子:
mysql> select * from students;
+----+-------+
| id | name |
+----+-------+
| 1 | Alice |
+----+-------+
1 row in set (0.00 sec)
Isolation.DEFAULT
? Connection.TRANSACTION_NONE
?默認(rèn)事務(wù)隔離級別,具體使用的數(shù)據(jù)庫事務(wù)隔離級別由底層決定。
提示
相當(dāng)于沒有設(shè)置,但具體行為由驅(qū)動決定。
Isolation.READ_UNCOMMITTED
?Connection.TRANSACTION_READ_UNCOMMITTED
?Read Uncommitted 是隔離級別最低的一種事務(wù)級別。在這種隔離級別下,一個事務(wù)會讀到另一個事務(wù)更新后但未提交的數(shù)據(jù),如果另一個事務(wù)回滾,那么當(dāng)前事務(wù)讀到的數(shù)據(jù)就是臟數(shù)據(jù)。
時間 | 事務(wù)1 | 事務(wù)2 | 效果 |
---|---|---|---|
T1 | set transaction isolation level read uncommitted; | ||
T2 | begin; | begin; | |
T3 | update students set name = 'bob' where id = 1; | ||
T4 | select * from students where id = 1; | 可以看到 事務(wù)1 變更后的數(shù)據(jù) | |
T5 | rollback; | ||
T6 | select * from students where id = 1; | 可以看到 事務(wù)1 回滾后的數(shù)據(jù) | |
T7 | commit; |
Isolation.READ_COMMITTED
?Connection#TRANSACTION_READ_COMMITTED
?Read Committed 不可重復(fù)讀,是指在數(shù)據(jù)庫訪問中,一個事務(wù)范圍內(nèi)兩個相同的查詢卻返回了不同數(shù)據(jù)。
時間 | 事務(wù)1 | 事務(wù)2 | 效果 |
---|---|---|---|
T1 | set transaction isolation level read committed; | set transaction isolation level read committed; | |
T2 | begin; | begin; | |
T3 | select * from students where id = 1; | 原始數(shù)據(jù) | |
T4 | update students set name = 'bob' where id = 1; | ||
T5 | select * from students where id = 1; | 此時 事務(wù)2 看到的仍然是 原始數(shù)據(jù) | |
T6 | commit; | ||
T7 | select * from students where id = 1; | 此時 事務(wù)2 再次查詢看到的數(shù)據(jù)和 原始數(shù)據(jù) 不一樣 | |
T8 | commit; |
Isolation.REPEATABLE_READ
?Connection#TRANSACTION_REPEATABLE_READ
?可重復(fù)讀(Repeatable Read),當(dāng)使用可重復(fù)讀隔離級別時,在事務(wù)執(zhí)行期間會鎖定該事務(wù)以任何方式引用的所有行。
在 Repeatable Read 隔離級別下,一個事務(wù)可能會遇到幻讀(Phantom Read)的問題。 幻讀是指,在一個事務(wù)中,第一次查詢某條記錄,發(fā)現(xiàn)沒有。但是,當(dāng)試圖更新這條不存在的記錄時,竟然能成功。并且,再次讀取同一條記錄,它就神奇地出現(xiàn)了。
時間 | 事務(wù)1 | 事務(wù)2 | 效果 |
---|---|---|---|
T1 | set transaction isolation level repeatable read; | set transaction isolation level repeatable read; | |
T2 | begin; | begin; | |
T3 | select * from students where id = 99; | 不存在的數(shù)據(jù) | |
T4 | insert into students (id, name) values (99, 'bob'); | ||
T5 | commit; | ||
T6 | update students set name = 'alice' where id = 99; | 可以成功更新 | |
T7 | select * from students where id = 99; | ||
T8 | commit; |
Isolation.SERIALIZABLE
? Connection#TRANSACTION_SERIALIZABLE
?提供嚴(yán)格的事務(wù)隔離。它要求事務(wù)序列化執(zhí)行,事務(wù)只能一個接著一個地執(zhí)行,不能并發(fā)執(zhí)行。因此,臟讀、不可重復(fù)讀、幻讀都不會出現(xiàn)。
?Serializable
? 隔離級別相當(dāng)于在開啟事務(wù)的時候,對整個數(shù)據(jù)庫加了 排他鎖,直到第一個事務(wù)被 commit 否則其它事務(wù)無法開始。 因此效率會大大下降,一般沒有沒有特別重要的情景,都不會使用 ?Serializable
?隔離級別。
更多建議: