Postgresql 如果要同时运行,如何编写能够正常工作的函数?

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

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