Postgres - ShareLock on Transaction

时间:2018-03-06 21:40:48

标签: transactions sqlalchemy deadlock postgresql-9.6

当多个进程尝试在表中插入同一行时,我收到事务死锁。插入中唯一具有非null值的列是对其具有唯一约束并且不是主键的列。我正在使用SQLAlchemy版本:1.1.15,psycopg2版本:2.7.3.2,python版本:3.4和PostgreSQL版本:Centos 7上的9.6.8。

以下是我的进程崩溃之前收到的错误:

psycopg2.extensions.TransactionDeadlockError: deadlock detected
DETAIL: Process X waits for ShareLock on transaction Z; blocked by process Y
Process Y waits for ShareLock on transaction W; blocked by process X
HINT: See server log for details
CONTEXT: while inserting index tuple (0, 125) in relation 'entity_short_name_unq'

以下是entity表的定义:

CREATE TABLE public.entity
(
    entity_id integer NOT NULL DEFAULT nextval('entity_entity_id_seq'::regclass),
    name character varying(50) COLLATE pg_catalog."default",
    short_name character varying(10) COLLATE pg_catalog."default" NOT NULL,
    description text COLLATE pg_catalog."default",
    CONSTRAINT pk_entity PRIMARY KEY (entity_id),
    CONSTRAINT entity_name_unq UNIQUE (name) DEFERRABLE INITIALLY DEFERRED,
    CONSTRAINT entity_short_name_unq UNIQUE (short_name) DEFERRABLE INITIALLY DEFERRED
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

根据数据库日志导致死锁的语句是:

begin;
insert into entity (name, short_name, description) values(null, 'LLL', null);
commit;

我能够通过打开三个终端来重现错误,连接到每个终端中的数据库并在事务中发出上述三个命令,确保所有三个事务(A,B,C)在我之前发出插入查询在任何一个中提交提交。

首先发出插入查询的事务(比如说A)在提交时成功。另外两个事务中的一个(比如B)报告了违反唯一约束的完整性错误,但另一个(比如C)显示死锁错误。

为什么C不将完整性错误报告为B? 我该怎么做才能避免这种僵局?

0 个答案:

没有答案