我需要为一个用户锁定行,以防止其他任何内容更改内容。
User A: call function lock_row() to lock row X
User B: call function lock_row() to lock row X (lock cant be created and "exception" should be triggered as row X is already locked)
当用户A和B使用相同的会话连接时,情况不可能。
那么如何确保这样的事情不会发生:
User A: check if lock == 0
User B: check if lock == 0
User A: lock == 0 so SET lock = 1
User B: lock == 0 is also here so SET lock = 1
我想通过触发器(行上的UPDATE)而不是直接在SQL语句上创建锁,而是通过函数来允许用户在意外错误的情况下释放锁。
如何创建"关键部分"?如何确保我的函数中的关键部分能够正确执行?
PostgreSQL版本9.x。
答案 0 :(得分:0)
您需要的只是同一交易中 独家row lock 。
如果无法获取锁定(由另一个交易锁定),请添加 NOWAIT
以使交易立即失败。
BEGIN;
SELECT 1
FROM tbl
WHERE tbl_id = x
FOR UPDATE NOWAIT;
- do something
COMMIT; -- lock released automatically
根据您打算做的事情,限制较少的FOR NO KEY UPDATE
可能已经足够了。
相关:
或者,您可以将SELECT
或完整事务包装到函数中。同样的效果。异常总是会跳过整个事务(除非您捕获错误)。
咨询锁是另一种选择,但不太可靠。当您可以通过行级锁实现相同的功能时,无需回退到这个通用工具。