Postgresql 如果要同时运行,如何编写能够正常工作的函数?
我有一个表一些表(id整数,x整数) 如果要同时运行,如何编写能够正常工作的函数? 以下是我当前的版本:Postgresql 如果要同时运行,如何编写能够正常工作的函数?,postgresql,concurrency,Postgresql,Concurrency,我有一个表一些表(id整数,x整数) 如果要同时运行,如何编写能够正常工作的函数? 以下是我当前的版本: CREATE OR REPLACE FUNCTION actualize_table( IN p_id INTEGER, IN p_x INTEGER, OUT p_created BOOLEAN ) LANGUAGE plpgsql SECURITY DEFINER AS $BODY$ BEGIN IF EXISTS(SELECT 1 FROM some_tabl
CREATE OR REPLACE FUNCTION actualize_table(
IN p_id INTEGER,
IN p_x INTEGER,
OUT p_created BOOLEAN
)
LANGUAGE plpgsql
SECURITY DEFINER
AS $BODY$
BEGIN
IF EXISTS(SELECT 1 FROM some_table WHERE id = p_id FOR SHARE) THEN
p_created = FALSE;
ELSE
p_created = TRUE;
END IF;
INSERT INTO some_table (id) VALUES (p_id) ON CONFLICT (id) DO UPDATE SET x = p_x;
END;
$BODY$;
但,若row不存在,该函数似乎无法正常工作,所以select上不会有锁。
我的意思是,FOR SHARE
在这种情况下能正常工作吗?
您觉得怎么样?我从postgresql文档中找到了解决方案: UPDATE、INSERT和DELETE语句集在至少一个 行受影响,如果没有行受影响,则为false
如果行不存在,它就不能被锁定,对此你无能为力。在任何情况下,您都可以在
ELSE
条款中找到。了解您要保护的条件是什么会很有帮助?@AdrianKlaver我想防止出现这样的情况:两个并行事务都可以看到没有id=p_id的行,因此p_created=TRUE适用于这两个事务。
INSERT INTO some_table (id)
VALUES (p_id)
ON CONFLICT (id) DO NOTHING;
IF FOUND THEN
p_created = TRUE;
ELSE
p_created = FALSE;
END IF;