gpt4 book ai didi

postgresql - Postgres : how to add unique identifier to table

转载 作者:行者123 更新时间:2023-11-29 13:28:07 25 4
gpt4 key购买 nike

我有下表:

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”;此函数在插入另一个表时从触发器调用,插入在事务内调用。隔离级别设置为 READ COMMITED,Debian Wheezy 上的 postgres 9.1。我做错了什么?

最佳答案

我通过以下方式了解它是如何发生的。

  1. 两个进程(线程)使用相同的myid同时调用该函数。
  2. 两个线程都成功地执行了SELECT nid INTO .. 查询,并且看到- 现在表中没有这样的myid
  3. 两个线程都进入IF NOT FOUND THEN
  4. 线程 1 执行 INSERT INTO myid(myid) 并无错误地提交事务
  5. 线程 2 执行 INSERT INTO myid(myid) 并失败,因为表中已存在相同的 myid 值(PRIMARY KEY 约束)。

为什么线程 2 在自己的事务中看到其他事务提交的数据?由于“不可重复读取”现象,这可以通过 READ COMMITTED 隔离 ( http://www.postgresql.org/docs/9.2/static/transaction-iso.html ) 实现。

关于postgresql - Postgres : how to add unique identifier to table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29894068/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com