資料庫事務的隔離等級,英語叫做 Transaction Isolation Level。 最近在給客戶維護項目的時候,對一個表在兩個進程中同時做更新和查詢時碰到了死鎖(DeadLock),數據表裡有幾百萬上千萬條記錄,上面的處理當時是更新幾千條記錄, 查詢整張表。 這是前提,為了搞明白這個死鎖,大概 ...
資料庫事務的隔離等級,英語叫做 Transaction Isolation Level。
最近在給客戶維護項目的時候,對一個表在兩個進程中同時做更新和查詢時碰到了死鎖(DeadLock),數據表裡有幾百萬上千萬條記錄,上面的處理當時是更新幾千條記錄,
查詢整張表。
這是前提,為了搞明白這個死鎖,大概涉及到死鎖,隔離等級,鎖升級以及Trace跟蹤的內容,陸續整理出來,今天說說隔離等級。
概要
有下麵3種讀取不具合的現象,首先說說關於RDBMS的ACID特性的I(Isolation-隔離性)
·臟讀
·不可重覆讀
·幻影讀
接著說說事務隔離等級的4個等級。
·Read uncommitted
·Read committed
·Repeatable read
·Serializable
越往下隔離等級越高,越往上隔離等級越低。
對於最高的隔離等級,上邊的3中讀取不具合現象就不會發生了。但是,系統性能就會有很大的損失。
大概可以總結為[想要提升系統性能就要接受一定程度的讀取不具合,如果即使性能低一些也沒有關係那就不會發生讀取上的不具合]
讀取不具合
說明一下這3中讀取不具合現象
臟讀
讀取到別的事務還沒有提交的數據的現象:
1.事務A要把記錄a更新到記錄b(還沒提交時)
2.事務B查詢了記錄
3.事務A做了回滾
4.事務B讀到了記錄b
這是把隔離等級設到最低級別了啊,還沒見過這樣的系統。
不可重覆讀
讀到了別的事務更新後的數據,導致出現了非連貫性的讀取操作。
1.事務A查詢了記錄,稱之為a
2.事務B把記錄a的內容更新到記錄b,並且提交了。
3.事務A對記錄a再次進行查詢,取得的內容已經變成了記錄b。
幻影讀
看到了其它事務插入的記錄導致出現的非連貫現象。
1.事務A查詢記錄時沒有記錄。
2.事務B插入記錄並提交。
3.事務A再次查詢記錄時取得了事務B插入的記錄。
是不是感覺和不可重覆讀有點像呀,重點在是插入操作還是更新操作。
另外,下麵也是幻影讀哦
1.事務A統計記錄是X件。
2.事務B插入記錄並提交。
3.事務A再次統計記錄,取得的件數是X+1件。
這就是關於讀取操作的3種不具合現象。
事務隔離等級和讀取不具合的關係
臟讀 | 不可重覆讀 | 幻影讀 | |
Read uncommitted | 發生 | 發生 | 發生 |
Read committed | 不發生 | 發生 | 發生 |
Repeatable read | 不發生 | 不發生 | 發生 |
Serializable | 不發生 | 不發生 | 不發生 |
這樣看是不是覺得每次都選擇設置隔離等級為Serializable(可序列化)就一勞永逸了呀,
其實隔離性設置高了也是有問題的啊。這文就不說明瞭,要不又是一大段,有興趣的調查下吧。
關於幾個重點
·設置隔離等級也不能說就一定可以保證不會發生對應的某種錯誤。和具體的資料庫實裝RDBMS有很大
關係,例如MySQL的REPEATABLE READ的隔離等級也不會發生幻影讀。
·所謂的【保證不發生】,為了不發生錯誤而採取的處理方法也因資料庫RDBMS而不同。在發生異常時
有些資料庫會報異常,有的會等待事務結束。
·資料庫RDBMS的預設隔離等級各異,對應的隔離級別也不同。
MySQL(InnoDB) | REPEATABLE READ | ||
PostgreSQL | READ COMMITTED | ||
Oracle | READ COMMITTED | ||
SQL Server | READ COMMITTED |
就這樣,寫這點也挺花時間,有空再更新關於SQLServer的死鎖,鎖升級和Trace跟蹤。