我试图通过锁定和解锁某些行来绕过双重写入。
我有一个表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;
在另一个用户尝试编辑同一行的时间之间,他会收到一条消息。
答案 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
选项 - 所有竞争查询。