如何手动锁定和解锁一行?

时间:2014-05-16 18:28:30

标签: postgresql concurrency transactions sql-update

我试图通过锁定和解锁某些行来绕过双重写入。

我有一个表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;

在另一个用户尝试编辑同一行的时间之间,他会收到一条消息。

1 个答案:

答案 0 :(得分:1)

锁定在交易结束时释放。因此,您需要保持事务 open 以维护锁定并在单个事务中执行所有操作:

BEGIN;
SELECT * FROM personnel WHERE id = 12 FOR UPDATE NOWAIT;  -- row level locking
COMMIT;

BEGIN;
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

  

除了表级锁外,还有行级锁,可以   是独家锁或共享锁。一个独家的行级锁定   更新行时自动获取特定行或   删除。锁定一直持续到事务提交或回滚,   就像表级锁一样。行级锁不会影响数据   查询;他们只阻止作者到同一行

要立即尝试同时执行此操作失败,请使用 NOWAIT 选项 - 所有竞争查询。