Postgresql Postgres:如何向表中添加唯一标识符

Postgresql Postgres:如何向表中添加唯一标识符,postgresql,stored-procedures,constraints,unique,isolation-level,Postgresql,Stored Procedures,Constraints,Unique,Isolation Level,我有下表: CREATE TABLE myid ( nid bigserial NOT NULL, myid character varying NOT NULL, CONSTRAINT myid_pkey PRIMARY KEY (myid ) ) 现在,我想使用以下函数将记录添加到此表中: CREATE FUNCTION getmyid(_myid character varying) RETURNS bigint AS $BODY$ --version 1.1 2015-

我有下表:

CREATE TABLE myid
(
  nid bigserial NOT NULL,
  myid character varying NOT NULL,
  CONSTRAINT myid_pkey PRIMARY KEY (myid )
)
现在,我想使用以下函数将记录添加到此表中:

CREATE FUNCTION getmyid(_myid character varying)
  RETURNS bigint AS
$BODY$ --version 1.1 2015-03-04 08:16
DECLARE
  p_nid bigint;
BEGIN
  SELECT nid INTO p_nid FROM myid WHERE myid=_myid FOR UPDATE;
  IF NOT FOUND THEN
    INSERT INTO myid(myid) VALUES(_myid) RETURNING nid INTO p_nid;
  END IF;
  RETURN p_nid;
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
一般来说,它工作正常,但在高负载下,此函数有时会失败,因为重复的键值违反了唯一约束myid_pkey; 此函数在另一个表的insert上从触发器调用,insert在事务中调用。针对Debian哮喘病的阅读承诺、postgres 9.1设置隔离级别。
我做错了什么?

我知道它是如何发生的

两个processesthread使用相同的myid同时调用函数。 两个线程都成功地将SELECT nid执行到。。查询,然后查看-现在表中没有这样的myid。 如果未找到,则两个线程都将进入 线程1执行INSERT INTO myidmyid并提交事务,没有错误 线程2执行INSERT INTO myidmyid并失败,因为表主键约束中已经存在相同的myid值。 为什么线程2在自己的事务中看到其他事务提交的数据?
因为“不可重复读取”现象,这在读取提交隔离中是可能的。

为什么会出现if?插入myidmyid值有什么问题?\u myid不存在时从myid中选择1,其中myid=\u myid?[可以在普通SQL中完成,而不需要plpgsql]@wildplasser我想说的是相同的:@wildplasser:如果两个会话同时进行,这仍然可能导致重复的键值,但我同意这更有效,它不能解决隐式无法解决的并发问题。可能会有额外的竞争,但我不希望像这样的小功能被抢占@Jarek try this