讀 - 修改 - 寫我們有一個簡單的表的Postgres 9.4死鎖檢測時,對單個表
given_entity{
UUID id;
TimeStamp due_time;
TimeStamp process_time;
}
這是一個使用彈簧數據 - 彈簧啓動(1.2.5.RELEASE)應用程序的應用程序jpa.1.2.5.RELEASE與hibernate-4.3.10.FINAL作爲jpa provier。
我們有5個這個應用程序的實例,每個實例都有一個每2秒運行一次的調度程序,並查詢數據庫中有最後2分鐘的due_time直到現在還沒有處理的行;
SELECT * FROM given_entity
WHERE process_time is null and due_time between now() and NOW() - INTERVAL '2 minutes'
FOR UPDATE
要求是上表的每一行都被恰好一個應用程序實例成功處理。 然後,應用程序實例處理這些行並在一個事務中更新其process_time字段。 這可能需要或可能不會超過2秒,這是調度程序間隔。 此外,我們沒有任何索引,但在此表上的PK索引。 值得注意的第二點是,這些實例可能會插入此表,這是由客戶端單獨調用的。
問題:在日誌中我看到的PostgreSQL此消息(很少,但它發生)
ERROR: deadlock detected
Detail: Process 10625 waits for ShareLock on transaction 25382449; blocked by process 10012.
Process 10012 waits for ShareLock on transaction 25382448; blocked by process 12238.
Process 12238 waits for AccessExclusiveLock on tuple (1371,45) of relation 19118 of database 19113; blocked by process 10625.
Hint: See server log for query details.
Where: while locking tuple (1371,45) in relation "given_entity"
問: 這是如何發生的呢? 我檢查了postgresql鎖並搜索了互聯網。我沒有發現只有一個簡單的表上可能存在死鎖的情況。 我也無法使用測試重現此錯誤。
你可以粘貼代碼更新表的位置嗎? **選擇更新**阻止其他交易的修改,人們應該小心。 –
爲了完全避免這些問題,可以使用Hibernate樂觀鎖定機制(除非有一些真正有效的理由來鎖定您想要更新的記錄)。也許這也可能有幫助:http://blog.2ndquadrant.com/postgresql-anti-patterns-read-modify-write-cycles/ –
爲了更新,我們只需更新process_time字段。像'UPDATE given_entity set process_time = now()where id =?' – Abareghi