简体   繁体   English

PostgreSQL 外键违规内部交易

[英]PostgreSQL foreign key violation inside transaction

I have a function with several queries inside, like this:我有一个 function 里面有几个查询,如下所示:

CREATE OR REPLACE FUNCTION public.myfunction(winningid integer, losingid integer)
 RETURNS void
 LANGUAGE plpgsql
AS $function$
begin

update partecipants set id_be=winningId where id_be=losingId;
...
many other updates and deletes regarding other tables
...

delete from business_entity where id_be=losingId;

end;
$function$
;

There is a foreign key between partecipants and business_entity:参与者和business_entity之间有一个外键:

ALTER TABLE partecipants ADD CONSTRAINT partecipants_fk FOREIGN KEY (id_be) REFERENCES business_entity(id_be)

Sometimes (like 1 in 1000 times) this function hangs with error:有时(如千分之一)此 function 挂起并出现错误:

error: update or delete on table "business_entity" violates foreign key constraint "partecipants_fk" on table "partecipants"
detail:
   'Key (id_be)=(315017) is still referenced from table "partecipants".

If I run the same function a second time, ends without error.如果我第二次运行相同的 function ,则结束没有错误。

How is this possible?这怎么可能?

As a background information, other processes are using (often also with locks) the tables involved in the function while is running.作为背景信息,其他进程在运行时正在使用(通常也带有锁)function 中涉及的表。

Concurrent transactions could add or modify rows in partecipants between your UPDATE and your DELETE so that the latter fails.并发事务可以在您的UPDATE和您的DELETE之间添加或修改partecipants中的行,以便后者失败。

If you want to avoid that, do both in a single statement:如果您想避免这种情况,请在一个语句中执行这两项操作:

WITH dummy AS (
   update partecipants set id_be=winningId where id_be=losingId
)
delete from business_entity where id_be=losingId;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM