【问题标题】:How to rectify the conflicts which occur at concurrent transactions in PostgreSQL如何纠正 PostgreSQL 并发事务中发生的冲突
【发布时间】:2013-08-31 22:26:09
【问题描述】:

我有function 其中checks pid 的maximum value 然后inserts 进入数据库。

但是当我有concurrent transactions!时它会引发conflict

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

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) 应该插入tablea,通过增加pid by +1,所以我不能删除我的 pid 来自 tablea,并且 pid 保持整数,以便我可以通过相同的 pid 插入另一条记录,并且流程也与 ppid 相同..

所以我应该改变我的表结构或任何其他方式来纠正并发事务中的冲突。

这就是我的整体概念的全部内容 sql fiddle demo

【问题讨论】:

  • 我使用 java Primefaces 作为 Springs 和休眠的用户界面。

标签: java postgresql transactions postgresql-9.1 postgresql-9.2


【解决方案1】:

永久有效地避免冲突的方法是从您的表格中删除多余的pid。将sno 用于所有目的。并且不允许直接输入该列,因此无法绕过附加序列中的默认值。 sno 可以有间隙,这是设计使然。但它对于并发负载下的独特列来说完美无缺。之后的请求(稍后开始)会获得更高的序列号。这就是 serial 列的用途。

如果你真的需要一个无缝的“pid”,你可以用row_number()模拟一个:

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

现在,如果可以删除行,则合成的 pid 不稳定。但是,如果编号中可能存在空白,那么这个练习的意义何在?

【讨论】:

  • 我根据我的要求编辑了这个问题,所以请你帮我继续下一步
  • 我使用 sno 作为 pid 和 ppid 的复合主键,pid 是 party_id,ppid 是我在任何 pid 下 keeo 的子方......编辑的小提琴是在下面..我的要求@Erwin Brandstetter
【解决方案2】:

尝试这样的事情来减少冲突的机会:

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

为了完全避免冲突,您还可以将transaction isolation level 设置为可序列化(先阅读它以考虑利弊):

set transaction isolation level serializable;

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

【讨论】:

  • 我使用 sno 作为 pid 和 ppid 的复合主键,pid 是 party_id,ppid 是我在任何 pid 下 keeo 的子方......编辑的小提琴是在下面..在我的要求中
猜你喜欢
  • 2020-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
  • 2016-08-17
  • 2021-09-15
相关资源
最近更新 更多