您可以在两个并行会话中重现此问题:
第一个会话:
begin;
create table if not exists log(id bigint generated always as identity, t timestamp with time zone, message text not null);
注意第一个会话尚未提交,因此表格实际上并不存在。
第二个会话:
begin;
create table if not exists log(id bigint generated always as identity, t timestamp with time zone, message text not null);
第二个会话现在将被阻塞,因为第一个会话保留了“log”这个名称。但是目前还不知道保留它的事务是否会提交。
然后,当您提交第一个会话时,第二个会话会失败。
ERROR: duplicate key value violates unique constraint "pg_class_relname_nsp_index"
DETAIL: Key (relname, relnamespace)=(log_id_seq, 2200) already exists.
为避免此问题,您需要确保在获取某些常见咨询锁之后才执行检查表是否存在的操作:
begin;
select pg_advisory_xact_lock(12345);
create table if not exists log(id bigint generated always as identity, t timestamp with time zone, message text not null);
commit;