PostgreSQL學習手冊(七) 事物隔離

在SQL的標準中事物隔離級別分爲如下四種:
    1. 讀未提交(Read uncommitted)
    2. 讀已提交(Read committed)
    3. 可重複讀(Repeatable read)
    4. 可串行化(Serializable)
    然而PostgreSQL在9.1以前的版本中只是實現了其中兩種,即讀已提交和可串行化,若是在實際應用中選擇了另外兩種,那麼PostgreSQL 將會自動向更嚴格的隔離級別調整。在PostgreSQL v9.1的版本中提供了三種實現方式,即在原有的基礎上增長了可重複讀。在這篇博客中咱們將只是針對2)和4)進行說明和比較,由於在9.1中,3)和 4)的差異也是很是小的。 併發

  讀已提交 可串行化
PostgreSQL缺省隔離級別
其它事物未提交數據是否可見 不可見 不可見
執行效率
適用場景 簡單SQL邏輯,若是SQL語句中含有嵌套查詢,那麼在屢次SQL查詢中將極有可能得到不一樣版本的數據。 複雜SQL邏輯,特別是帶有嵌套的查詢比較適用。
SELECT查詢一致性時間點 從該SELECT查詢開始執行時,在此查詢執行期間,任何其它併發事物針對該查詢結果集的數據操做都將不會被本次查詢讀到,即本次查詢獲取的數據版本是與查詢開始執行時的數據版本相一致。 從該SELECT查詢所在事物開始時,在此查詢執行期間,任何其它併發事物針對該查詢結果集的數據操做都將不會被本次查詢讀到,即本次查詢獲取的數據版本是與查詢所在事物開始時的數據版本相一致。
同事物內的數據操做是否可見 好比在同一個事物內存在update和select操做,即便當前事物還沒有提交,update所做的修改,在當前事物後面的select中依然可見。 和讀已提交相同。
同事物內屢次相同的select所見的數據是否相同 不一樣,因爲該級別select的一致性時間點是該查詢開始執行時,而屢次查詢的時間點將確定不相同,若是在第一次查詢開始到第二次查詢開始之間,其它的併發事物修改並提交或當前事物僅修改了查詢將要獲取的數據,那麼這些數據操做的結果將會在第二個查詢中有所體現。 須要分兩步來講,對於同一事物內的修改若是發 生在兩次查詢語句之間,那麼第二個查詢將會看到這些修改的結果。然而對於其它併發事物的修改,將不會形成任何影響,即兩次select的結果是相同的。原 因顯而易見,該隔離級別的select一致性時間點是與事物開始時相一致的。
相同行數據的修改 若是此時兩個併發事物在修改同一行數據,先修 改的事物將會給該行加行級鎖,另一個事物將進入等待狀態,直到第一個事物操做該行結束。那麼假若第一個針對該行的修改操做最終被其事物回滾,第二個修改 操做在結束等待後,將直接修改該數據。然而若是第一個操做是被正常提交的話,那麼就須要進一步判斷該操做的類型,若是是刪除(delete)該行,第二個 修改操做將直接被忽略。若是是update該行的記錄,第二個修改操做則須要從新評估該行是否依然符合以前定義的修改條件。 和讀已提交隔離級別的機制基本相同,只是在第 一個修改操做提交後,第二個操做將再也不區分以前的修改是delete仍是update,而是直接並返回下面信息:Error: Can't serialize access due to concurrent update. 這是由於一個可串行化的事務在可串行化事務開始以後不能更改或者鎖住被其餘事務更改過的行。所以,當應用收到這樣的錯誤信息時,它應該退出當前的事務而後 從頭開始從新進行整個事務。在應用程序中,也應該有必要的代碼來專門處理該類錯誤。

    最後須要說明的是,在絕大多數的狀況下,讀已提交級別都可適用,並且該級別的併發效率更高。只有在比較特殊的狀況下,才手工將當前的事物隔離級別調整爲可串行化或可重複讀。 spa

相關文章
相關標籤/搜索