PostgreSQL的事務隔離分析
事務隔離
不懂的同學先補補概念
Reference: WiKi
隔離級別(Isolation levels)
有四種隔離級別:
- 可序列化(Serializable)
- 可重複讀(Repeatable reads)
- 提交讀(Read committed)
- 未提交讀(Read uncommitted)
正文
昨天被問了一個問題
當存在表test(id int)並有id=1
一條記錄, 那麼以下兩種操作會有什麼行為
- SessionA啟動事務後,SessionB做了更新id=2操作後,此時SessionA進行
UPDATE test SET id=id+2
,結果如何。 - SessionA啟動事務後,SessionB在事務中做了更新id=2操作後,先不提交,此時SessionA進行
UPDATE test SET id=id+2
,結果如何。
順著原始碼分析一下Postgres的是如何實現這種行為的。
提交讀(PostgreSQL的預設設定)
在提交讀的隔離級別下,
1.行為a的結果,SessionA 進行更新操作前查詢id變為2,更新操作成功後,查詢id為4。
2.行為b的結果,在SessionB提交前,SessionA的查詢id為1,如進行update操作,會一直阻塞直到SessionB提交或回滾,如SessionB成功提交查詢id為4,若SessionB回滾,查詢id結果為3。
行為1分析
SessionA的執行流程和普通的更新流程類似,先得到需要更新的row,然後進入heap_update
,對選定的row使用HeapTupleSatisfiesUpdate
進行版本(MVCC)檢查,由於SessionB的事務已經提交,所以會得到HeapTupleMayBeUpdated
的狀態,然後真正進行更新操作。(其中包括hot-update等各種流程就不在此描述)
行為2分析
此時的執行流程會和上面略有不同,當獲取目標row時候會得到尚未更新的那行row(因為此row雖然被標記為已刪除,但是因為SessionB尚未提交,所以仍然可見),對row進行更新版本檢查時,發現此row已經刪除,且SessionB還未提交,標記為HeapTupleBeingUpdated,接著嘗試取得該row的鎖(會等待直到SessionB提交或者回滾),之後檢查此row,如果被更新成功(SessionB提交),則進行row的refresh,對refresh後的row重新進行之前的操作,如果更新失敗(SessionB回滾),則直接更新。
可重複讀
在可重複讀的隔離級別下,
1.行為a的結果, SessionA 進行更新操作前查詢id為1,若進行更新操作, 則報錯 “could not serialize access due to concurrent update”。
2.行為b的結果, 在SessionB提交前,SessionA的查詢id為1,如進行update操作,會一直阻塞直到SessionB提交或回滾,如SessionB成功提交則報錯 “could not serialize access due to concurrent update”, 若SessionB回滾,則sessionA 的 UPDATE操作成功,查詢id結果為3,
行為1分析
和提交讀隔離級別的行為有點類似,但由於是可重複讀的快照,所以一開始取得的目標row是更新前的row,也就是id=1(提交讀id=2)的行,於是在更新操作的mvcc版本檢查中會認為此row是HeapTupleUpdated狀態,需要重新refresh row,在refresh對隔離級別進行檢查,如果大於等於可重複讀的級別,則拋錯。
行為2分析
和提交讀隔離級別的程式碼路徑一致,只是在 refresh row 時 對隔離級別進行檢查,因為此時為可重複讀,所以拋錯。
相關文章
- PostgreSQL事務隔離級別SQL
- 事務隔離(二):基於加鎖方式的事務隔離原理
- MySQL事務隔離MySql
- MySQL 事務隔離MySql
- SqlServer事務詳解(事務隔離性和隔離級別詳解)SQLServer
- MySQL事務的隔離級別MySql
- MySQL的事務隔離級別MySql
- PostgreSQL DBA(23) - MVCC#3(事務快照和隔離級別)SQLMVCC#
- MySQL 事務隔離級別MySql
- 4.MySQL--事務隔離MySql
- 事務、特性、隔離級別
- 資料庫事務隔離資料庫
- MySQL事務隔離級別MySql
- [Mysql]事務/隔離級別MySql
- 資料庫事務隔離級別分析----轉載資料庫
- 資料庫事務與事務的隔離級別資料庫
- 事務系統的隔離級別
- 深入淺出MYSQL的事務隔離MySql
- 理解mysql的事務隔離級別MySql
- SQL Server事務的隔離級別SQLServer
- MySQL 入門(3):事務隔離MySql
- mysql 事務,鎖,隔離機制MySql
- 理解MySQL事務隔離級別MySql
- mysql修改事務隔離級別MySql
- Oracle-事務隔離級別Oracle
- JDBC 事務(一) 隔離級別JDBC
- 深入理解oracle的事務隔離性Oracle
- MySQL 的四種事務隔離級別MySql
- MySQL 事務的隔離級別初窺MySql
- MySQL的四種事務隔離級別MySql
- 事務可見性的判斷和事務隔離級別,PostgreSQL和MySQL實現上有啥區別MySql
- MySQL事務隔離級別和MVCCMySqlMVC
- mysql如何修改事務隔離級別MySql
- mysql事務隔離級別和鎖MySql
- 啥是 MySQL 事務隔離級別?MySql
- Mysql 四種事務隔離級別MySql
- Mysql鎖與事務隔離級別MySql
- 資料庫事務隔離級別資料庫