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