PostgreSQL的事務隔離分析

2021-09-23 20:08:51 字數 1729 閱讀 3654

不懂的同學先補補概念

reference: wiki

隔離級別(isolation levels)

有四種隔離級別:

昨天被問了乙個問題

當存在表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的是如何實現這種行為的。

在提交讀的隔離級別下,

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 函式 事務隔離級別 實踐

過程大致意思 驗證 func 函式中依次呼叫 funca,funcb函式,三個函式中均有update操作,看看三個函式的select 是否可檢視未提交的update 表 create table public.audit id text collate pg catalog.default name...

事務的隔離級別舉例 事務的隔離級別

乙個事務是乙個完整的業務邏輯單元,不能再分,要麼全部執行成功,要麼全部失敗。比如 a給b轉賬100元,a的銀行卡就會少100元,b的銀行卡就會多100元,整個過程要麼全部執行成功,要麼全部失敗。a 原子性。事務是最小的業務邏輯單元。b 一致性。乙個事務必須保證多條dml語句同時成功或失敗。c 隔離性...

PostGreSQL 事務操作

一 隔離問題及隔離級別 1 隔離問題 a 髒讀 乙個事務讀到另乙個事務沒有提交的資料 b 不可重複讀 乙個事務讀到另乙個事務已提交的資料 update delete 乙個事務重新執行查詢,發現資料因被另乙個已經提交的事務 update 操作而改變 c 虛讀 幻讀 乙個事務讀到另乙個事務已提交的資料 ...