Postgresql

在已打開的事務中是否仍然可以使用已刪除(或更改)的功能?

  • December 24, 2017

我發現

但是沒有答案,並且與我的問題不完全相同(儘管非常相似)。


假設我執行以下操作:

  1. 創建一個函式myfunc()
  2. 從客戶端 A 開始事務
  3. 從客戶端 B 開始事務
  4. 在事務B中,使用“創建或替換函式”修改定義myfunc()
  5. 送出事務 B
  6. myfunc()來自事務 A 的呼叫

第 6 步會發生什麼? 我是否呼叫了步驟 1 中定義的原始函式?還是第 4 步中的修改後的表格(在第 5 步中送出)?


如果函式在第 4 步中被刪除而不是被修改,那麼第 6 步會失敗還是成功?(這可能是同一個問題,但修改可能會有所不同。)


關於這個的文件在哪裡?

第 6 步會發生什麼?

事務 A 立即看到更新後的函式定義myfunc()。(但請看下面記憶體的效果。)

如果函式在第 4 步中被刪除而不是被修改,那麼第 6 步會失敗還是成功?

它會失敗。(但請看下面記憶體的效果。)

Postgres DDL 命令是完全事務性的。雖然事務 B 未送出,但兩個事務將繼續看到函式的不同版本。但是並發事務確實會在系統目錄中看到***已送出的更改。***在預設隔離級別中似乎很明顯READ COMMITTED。但是您甚至無法通過隔離級別REPEATABLE READSERIALIZABLE.

如果您應該在事務 B 送出更改之前呼叫事務 A 中的函式,則本地記憶體可能會干擾。在我的測試中,在下一個呼叫知道更改並相應地回答之前,還有一個呼叫與記憶體(舊)函式一起工作。

我沒有找到系統目錄記憶體如何準確地表現這一點的文件(仍然可能存在於某處)。我不相信最後一點(從記憶體中再接一個電話)是最好的行為。


順便說一句,您的步驟 3. - 5. 可以減少到只有 4.,沒有任何區別。顯式或隱式事務包裝器的工作方式相同:

  1. 從客戶端 B 開始一個事務

  2. 在事務 B 中,使用“創建或替換函式”來修改 myfunc() 的定義

  3. 送出事務 B

引用自:https://dba.stackexchange.com/questions/193875