我想鎖定一行,直到他無限期地使用該行,並且他必須在完成時解鎖。所以其他用戶將無法爲自己鎖定此行。有可能在數據庫級別上做?PostgreSQL無限期地鎖定行
1
A
回答
1
你可以用一個長壽命的交易來做到這一點,但是會有性能問題。這聽起來更像是樂觀併發控制的工作。
你可以只是打開一個交易,並做一個SELECT 1 FROM mytable WHERE clause to match row FOR UPDATE;
。然後保持交易開放直到完成。問題在於它可能導致真空問題,導致表和索引膨脹,其中表被填充刪除的數據並且索引填滿指向過時塊的條目。
使用advisory lock會更好。您仍然必須保持連接處於鎖定狀態,但它不必保持閒置閒置事務,所以影響要小得多。但是,希望更新行的事務必須顯式檢查是否存在衝突的諮詢鎖,否則它們可以像鎖未鎖定一樣繼續。這種方法對大量表格(由於諮詢鎖定名稱空間有限)或大量併發鎖定(由於連接數量)也很差。
如果您無法確保您的客戶端應用程序始終明確獲取諮詢鎖,則可以使用觸發器來檢查諮詢鎖並等待它。但是,這可能會造成死鎖問題。
因此,最好的方法可能是記錄用戶ID的locked_by
字段和記錄鎖定時間的locked_time
字段。在應用程序級別和/或觸發器上執行。要處理併發嘗試獲取鎖定,您可以使用optimistic concurrency control技術,其中UPDATE
上的WHERE
子句設置locked_by
和locked_time
將不匹配,如果其他人首先到達那裏,則rowcount將爲零,並且您將知道您丟失了比賽的鎖定,必須重新檢查。 WHERE
條款通常測試locked_by
和locked_time
。所以,你會寫類似:
UPDATE t
SET locked_by = 'me' AND locked_time = current_timestamp
WHERE locked_by IS NULL AND locked_time IS NULL
AND id = [ID of row to update];
(這是一個簡化的樂觀鎖定模式,抓住一個鎖,在這裏你如果別人跳了做了一個整個事務不介意如果你想更嚴格的順序。 ,您使用行版本列或檢查last_modified列沒有更改。)
相關問題
- 1. Weblogic 11g無限期鎖定
- 2. PostgreSQL和鎖定
- 3. 無限期地雙擊運行間隔
- 4. iPhone:無限期地在後臺運行
- 5. PostgreSQL鎖定模式
- 6. 鎖定新插入的行[PostgreSQL]
- 7. PostgreSQL鎖定行之前刪除?
- 8. 無法理解PostgreSQL有關FOR UPDATE行鎖定的文檔
- 9. Postgresql鎖死鎖
- 10. 最輕鎖定在PostgreSQL中
- 11. Postgresql函數鎖定錯誤
- 12. 鎖定表像PostgreSQL的
- 13. PostgreSQL表鎖定衝突
- 14. Python的sys.exit行爲,當一個非守護線程無限期地等待鎖定
- 15. 死鎖與無限期延期有什麼區別?
- 16. 遊標無限期運行
- 17. 的CocoaPods無限期運行,
- 18. PostgreSQL ALTER TABLE顯式鎖定不能按預期工作
- 19. Postgresql使用臨時表進行更新鎖定行
- 20. postgresql死鎖
- 21. PostgreSQL鎖表
- 22. PostgreSQL鎖問題
- 23. 線程鎖無限等待
- 24. Golang http連接無限期地持續
- 25. 「tfx登錄」無限期地坐在
- 26. 爲什麼condition_variable無限期地等待
- 27. 方法無限期地評估
- 28. 的iOS AVFoundation captureStillImageAsynchronouslyFromConnection:completionHandler:無限期地掛起
- 29. Perforce CLI無限期地掛起
看起來像查詢更新所有行,其中「locked_by IS NULL AND locked_time IS NULL」,但如何更新只有一行?我認爲可能是應用程序正在下降並且行保持鎖定狀態,但是當用戶重新啓動程序時,lock_by ='me'所在的行已經存在,因此他需要先將它取出。 PS抱歉我的英語 – Miles
@Miles是的,而是。應該包含感興趣的ID。固定。 –
@Miles至於應用程序失敗,在「無限期鎖定」的同時,您不能輕易「在崩潰時自動解鎖」。您可能不得不依賴於PostgreSQL的開放式TCP連接,無論是建議性鎖定還是長時間運行的tx(但是如果數據庫處於大量寫入負載下,長時間運行的tx真的很糟糕)。 –