下表顯示了不同隔離級別允許的併發副作用。
隔離級別 |
髒讀 |
非重複讀取 |
幻像讀 |
未提交讀 read uncommitted |
是 |
是 |
是 |
已提交讀 read committed |
|
是 |
是 |
可重複讀 repeatable read |
|
|
是 |
可序列化 |
|
|
|
髒讀(Dirtyread)——含義和它的名字一樣壞、允許讀一個沒有提交的,或“髒”的數據。這是 在打開其他用戶正在寫入的 OS文件,並讀取正好在那裏的數據時所獲得的結果。數據的完整性被損 害,外碼被幹擾,惟一的約束被忽略。
特點:能接收到在任何時間在數據庫中都不會存在的(mysql中會出現示提交的)答案
非重複讀取——這只不過意味着讀者在時間T1 讀取一個行,並試圖在時間 T2 再次讀取那個行,
該行可能已經更改。它可能已經消失,它可能已經被更新,等等。
特點:一個事務中兩次讀的內空不一致
幻像讀(Phantomread)——這意味着,如果在時間 T1 執行了一個查詢,並在時間 T2 再次執行,附加的行可能已經添加到數據庫中,它將影響結果。這與非重複讀取不同,在這種情況下,已經讀取 的數據沒有改變,但有更多的數據滿足查詢標準。
特點:一個事務中兩次查詢的條數不一致,會多。
實現方式:
已提交讀 read committed:
當數據被更新時,將阻塞查詢:此會話必須在該行等待,直到持有獨佔鎖定的事務提交;防止髒讀
可重複讀 repeatable read(oracle無些隔離級別)
當數據被查詢時,將阻塞修改:一個共享讀取鎖定防止其他的會話修改已經讀取的數據;會有死鎖。防止非重複讀
READCOMMITTED:結果在語句開始的那一刻就固定
SERIALIZABLE: 事務結果在事務開始的那一刻就固定
(本事務更新的結果本事務中再次查詢可以看到,其它事務的修改本事務查詢看不到)
其中:Oracle實現SERIALIZABLE 事務方式:原本通常在語句級得到的讀一致性現在可以擴展到務事級。
SQL標準所定義的默認事務隔離級別是SERIALIZABLE |
Oracle Oracle 的默認事務隔離級別是READ COMMITTED Oracle數據庫支持READ COMMITTED 和 SERIALIZABLE這兩種事務隔離級別。所以Oracle不支持髒讀。 ORACLE提供了SQL92標準中的read committed和serializable,同時提供了非SQL92標準的read-only。 read-only與serializable的區別:read-only不允許在本事務中進行DM操作。 |
MySQL MySQL的默認事務隔離級別是Repeatable Read 由於應用next-key lock鎖,避免了幻讀。 用戶可以用SET TRANSACTION語句改變單個會話或者所有新進連接的隔離級別。它的語法如下: SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE} 注意:默認的行爲(不帶session和global)是爲下一個(未開始)事務設置隔離級別。如果你使用GLOBAL關鍵字,語句在全局對從那點開始創建的所有新連接(除了不存在的連接)設置默認事務級別。你需要SUPER權限來做這個。使用SESSION 關鍵字爲將來在當前連接上執行的事務設置默認事務級別。 查看隔離級別: SELECT @@tx_isolation; |