我试图通过锁定和解锁某些行来避免重复写入。
我有一个表personnel
,只要用户尝试编辑一行,我就想锁定该行。
所以
BEGIN;
// I guess I have to lock it somehow here
SELECT * FROM personnel WHERE id = 12;
COMMIT;
一旦完成编辑,我想以相同的样式提交 UPDATE
:
BEGIN;
//Unlocking
UPDATE personnel SET ...
WHERE id = 12;
COMMIT;
在此期间,当另一个用户试图编辑同一行时,他会收到一条消息。
最佳答案
锁在事务结束时释放。因此,您需要保持事务打开以维持锁定并在单个事务中完成所有操作:
BEGIN;
SELECT * FROM personnel WHERE id = 12 <b>FOR UPDATE NOWAIT</b>; -- row level locking
<strike>COMMIT;</strike>
<strike>BEGIN;</strike>
UPDATE personnel SET ...
WHERE id = 12;
COMMIT;
或者,您可以使用限制较少的 FOR SHARE
子句。
Details in the manual on SELECT
in the chapter "The Locking Clause".
允许并发读取。引用章节"Row-level Locks" in the manual :
In addition to table-level locks, there are row-level locks, which can be exclusive or shared locks. An exclusive row-level lock on a specific row is automatically acquired when the row is updated or deleted. The lock is held until the transaction commits or rolls back, just like table-level locks. Row-level locks do not affect data querying; they block only writers to the same row.
要让并发尝试立即失败,请使用 NOWAIT
选项 - 对于所有竞争查询。
关于postgresql - 如何手动锁定和解锁一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23702284/