PostgreSQL中事務的隔離級別


  數據庫事務的隔離級別有以下四種:

(1)讀未提交(READ UNCOMMITTED)

(2)讀已提交(READ COMMITTED)

(3)重復讀(REPEATABLE READ)

(4)串行化(SERIALIZABLE)

    對於並發事務,我們不希望發生的行為如下:

(1)臟讀:一個事務讀取了另一個未提交的事務寫入的數據。

(2)不可重復讀:一個事務重新讀取前面讀取過的數據時,發現該數據已改變。

(3)幻讀:一個事務開始后,需要根據數據庫中現有的數據做一些更新,於是重新執行一個查詢,返回符合查詢條件的行,這時發現這些行因為其它最近提交的事務而發生了改變,導致現有事務如果再進行下去可能發發生邏輯上的錯誤。

    不同事務隔離級別的行為見表:

隔離級別 臟讀 不可重復讀 幻讀
讀未提交 可能 可能 可能
讀已提交 不可能 可能 可能
重復讀 不可能 不可能 可能
可串行化 不可能 不可能 不可能
PostgreSQL里默認的隔離級別是"讀已提交"。

如何很好的理解不可重復讀和幻讀的區別:

精煉解釋:

不可重復讀的重點是修改:

同樣的條件, 你讀取過的數據, 再次讀取出來發現值不一樣了

幻讀的重點在於新增或者刪除

同樣的條件, 第1次和第2次讀出來的記錄數不一樣

 

當然, 從總的結果來看, 似乎兩者都表現為兩次讀取的結果不一致.

但如果你從控制的角度來看, 兩者的區別就比較大
對於前者, 只需要鎖住滿足條件的記錄
對於后者, 要鎖住滿足條件及其相近的記錄

 

詳細說明:

1) "不可重復讀" 是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據。那么,在第一個事務中的兩次讀數據之間,由於第二個事務的修改,那么第一個事務兩次讀到的的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重復讀。例如,一個編輯人員兩次讀取同一文檔,但在兩次讀取之間,作者重寫了該文檔。當編輯人員第二次讀取文檔時,文檔已更改。原始讀取不可重復。如果只有在作者全部完成編寫后編輯人員才可以讀取文檔,則可以避免該問題

要避免這種情況,通常可以用 set tran isolation level repeatable read 來設置隔離級別,這樣事務A 在兩次讀取表T中的數據時,事務B如果企圖更改表T中的數據(細節到事務A讀取數據)時,就會被阻塞,知道事務A提交! 這樣就保證了,事務A兩次讀取的數據的一致性。

2)幻覺讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。例如,一個編輯人員更改作者提交的文檔,但當生產部門將其更改內容合並到該文檔的主復本時,發現作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產部門完成對原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM