是否有一种锁定表的方式,指定只应阻止具有特定值的插入? 例如,我有表“任务”和表“子任务”我需要一个操作,当任务关闭时,也应关闭与其相关且仍然打开的子任务。所以我想:
是否可以执行我在步骤2中描述的操作?如果不是(或者如果有更好的方法),我怎样才能在这种情况下获得安全的并发?
答案 0 :(得分:1)
最好的方法是自己创建一行!但您可以在交易结束时删除它。这是怎么回事
CREATE OR REPLACE FUNCTION ....
AS $$
BEGIN
INSERT INTO subtasks VALUE(pk, ...) ON CONFLICT (id) DO NOTHING;
GET DIAGNOSTICS inserted = ROW_COUNT
if inserted THEN
DELETE from subtasks where pk = id
endif;
COMMIT;
$$ LANGUAGE plpgsql;
请注意,在上面的代码中INSERT ON CONFLICT实际上并未对现有数据进行任何更改。它将返回更改的行数。如果没有更改行,则插入的变量将保持为零。
这里发生的事情是,在您的交易中插入了记录,任何其他连接都无法保存相同的记录。您可以通过使用psql打开与数据库的连接来确认这一点。然后做
begin;
insert ...
# just wait here
commit;
而在另一个中,尝试相同的插入,你会看到它挂起。插入是否成功取决于您是在第一个psql连接中提交还是回滚。
答案 1 :(得分:0)
您无法锁定特定值的表格,但在您的情况下,此解决方案将适用:在子任务中插入时创建触发器,并在此触发器中检查相应的任务是否已关闭。如果任务已关闭,则不允许插入。
任务关闭后,任务上的另一个触发器将关闭所有相应的子任务。