關於postgresql中事務隔離的總結


1 介紹

具有基本知識的DBA都知道,PostgreSQL在控制數據的一致性是通過使用一種多版本模型來維護的,也就是常說的多版本並發控制MVCC。這也就意味着每一個sql語句看到的都只是一小段時間的數據庫快照,或者稱為版本,而並不關心底層的數據文件當中的當前狀態。這樣帶來的好處就是保護每一個會話中的事務不受到其他會話的影響,提供了非常好的事務隔離機制。MVCC並發控制模型相對於鎖機制的優點在於,查詢數據的鎖請求與寫數據的鎖請求並不沖突,所以,讀不會阻塞寫,寫也不會阻塞讀。

2 事務隔離

其實說起事務隔離,可能偏向於理論上一些,但是對於數DBA人員來說,這個需要牢牢掌握,因為很多時候在排查異常問題的時候,需要分析每一個sql、每一個事務都對數據庫進行了哪些操作,為什么會導致數據不一致的原因等等。

sql標准定義了四種隔離級別:讀未提交、讀已提交、讀可重復、可序列化。四種關系層層遞進,越來越嚴格。

  • 讀未提交 Read uncommitted
    解釋就是一個事務讀到了另一個事務未提交的數據,一旦另一個事務回滾了,那么讀到的數據就是有問題的。這種現象就是臟讀了。

  • 讀已提交 Read committed
    讀已經提交的數據能夠解決臟讀的問題,因為這個事務需要等待另一個事務提交后才能讀取數據。但是該級別有一個問題,重復讀的時候可能會產生不同的數據,這是因為該事務讀取的兩次過程中,這些數據並沒有鎖住 ,還是可以處於能夠修改(update和delete)的。該級別是postgresql默認的級別。

  • 讀可重復 Repeatable read
    該級別解決了讀已提交的不可重復讀的問題,在事務開啟的時候,不能再修改操作了,直到該事務提交。該級別是mysql,Oracle,sql server默認的級別。但是在該級別,還是會出現幻讀的問題,幻讀和可重復讀非常類似,都是兩次查詢的結果不一致,可以這么理解,一個事務在插入一個檢查過不存在的記錄時,發現數據已經存在了,之前檢查的結果就像幻覺一樣,這是因為已經插入了新的數據導致的。

區別需要從機制來看,讀某一行數據,會給行加行排他鎖,事務無法修改數據,重復讀就不會出現數據不一致的問題,但是並沒有加表鎖,還是可以insert數據的。這就導致了后面查詢數據變多了。mysql會出現幻讀,pg不會。

  • 序列化 Serializable
    序列化是最高的事務隔離級別,在該級別下,事務是按照串行化的順序執行,可以避免臟讀,重復讀,幻讀。但是可想而知,所有事務都是按照串行化順序執行,那怎么保證高並發呢?這種數據庫必然性能非常低下,幾乎沒有數據庫會達到這種級別。

下表概括了SQL標准和PG實現的事務隔離級別中的描述

隔離級別 臟讀 不可重復讀 幻讀 序列化異常
讀未提交 允許,但不在PG中 可能 可能 可能
讀已提交 不可能 可能 可能 可能
可重復讀 不可能 不可能 允許,但不在PG中 可能
可序列化 不可能 不可能 不可能 不可能

3 總結

了解事務隔離對DBA非常重要,DBA可以根據業務的需求更改數據庫的默認隔離級別,預期達到性能的最大化。


免責聲明!

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



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