繁体   English   中英

如何纠正PostgreSQL中并发事务时发生的冲突

[英]How to rectify the conflicts which occur at concurrent transactions in PostgreSQL

我有function ,其checks所述maximum value的PID,然后inserts到数据库中。

但这在我有concurrent transactions!时引发conflict concurrent transactions!

那么我该如何避免这种冲突!

create table tablea(
  sno serial,
  pid integer,
  ppid integer,
  pname text
  );

-此函数检查pid的最大值,然后插入数据库中。

CREATE OR REPLACE FUNCTION insert_details(_pname text)
RETURNS void AS
$BODY$
declare
    _pid int;
begin
   _pid := (select MAX(pid) from tablea);
   _pid := coalesce(_pid, 0) + 1;

   insert into tablea(pid,pname)
   values(_pid,_pname);
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

--(Sub Party)This is the function checks the maximum value of ppid and then inserts into the database.(sub-Party)

CREATE OR REPLACE FUNCTION insert_details(_pid int,_pname text)
RETURNS void AS
$BODY$
declare
        _ppid int;
begin
   _ppid := (select MAX(ppid) from tablea where pid=_pid);
   _ppid := coalesce(_ppid, 0) + 1;

   insert into tablea(pid,ppid,pname)
   values (_pid,_ppid,_pname);
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

我的要求 :当我从前端点击一个submit按钮时,我的field(pname)应该通过将pid by +1插入到tablea ,因此我无法从tablea中删除我的pid,并且pid保持为整数,因此我可以通过相同的pid插入另一条记录,流程也与ppid相同。

因此,我应该更改表结构还是其他任何方法来纠正并发事务中的冲突。

这就是我的整个概念全部关于sql小提琴演示的方式

要永久有效地避免冲突,可以从表中删除冗余pid 出于所有目的使用sno代替。 并且禁止直接输入该列,以免绕过附加序列中的默认值。 sno可能存在间隙,这是设计sno 但是对于并发负载下的唯一列,它可以完美地工作。 之后的请求(稍后开始)将获得更高的序列号。 这就是serial列的优点。

如果您确实需要一个无缝的“ pid”,则可以使用row_number()模拟一个:

SELECT *, row_number() OVER (ORDER BY sno) AS pid FROM tablea

现在,如果可以删除行,则合成的pid不稳定。 但是,如果毕竟在编号方面存在空白,那么此练习的意义是什么?

尝试这样的事情以减少冲突的可能性:

insert into tablea(pid,pname)
values(coalesce((select MAX(pid) from tablea), 0) + 1,_pname);

为了完全避免冲突,您还可以将事务隔离级别设置为可序列化(请先阅读该文档,以利弊):

set transaction isolation level serializable;

insert into tablea(pid,pname)
values(coalesce((select MAX(pid) from tablea), 0) + 1,_pname);

暂无
暂无

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

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