问题描述
嗨,汤姆
我们有一个存储的proc,如下所示:
这个过程是由一些Java API调用的。通常这工作得很好,但是当有2个Java会话并行运行时,如果表中不存在v_id,它会插入重复项。它们实际上不是重复的,因为主键是基于序列的,但是如果我们从id的角度考虑,它是重复的。
为了解决这个问题,如果我们使用FOR UPDATE子句到游标,它是否也有助于插入新的id以及?
收到您的来信真是太好了。非常感谢您的帮助。
致以最诚挚的问候,
阿舒
我们有一个存储的proc,如下所示:
Proc P1 (p_id in varchar2) is cursor c1 is select a,b,c from t1, t2 where t1.pk = t2.fk and t1.id = p_id ; v_id varchar2(10); Begin Open c1 (p_id); fetch c1 into v_id; close c1; If nvl(v_id,0) = 0 then insert into t1 (PK, id,...) values(sequence, v_id, .......); else update t1 set some_other_col = some_val where t1.id = v_id; end if; End;
这个过程是由一些Java API调用的。通常这工作得很好,但是当有2个Java会话并行运行时,如果表中不存在v_id,它会插入重复项。它们实际上不是重复的,因为主键是基于序列的,但是如果我们从id的角度考虑,它是重复的。
为了解决这个问题,如果我们使用FOR UPDATE子句到游标,它是否也有助于插入新的id以及?
收到您的来信真是太好了。非常感谢您的帮助。
致以最诚挚的问候,
阿舒
专家解答
如果每个ID值必须只有一行,有一种方法可以解决这个问题:
对它放置一个独特的约束!
选择更新无济于事。如果要添加新行,则查询将不返回任何内容。所以没有什么可以锁定来停止另一个会话。
其他一些观察结果:
我不明白您为什么要在光标中加入t2。您只是在插入/更新t1。因此,当没有子t2行时,这可能会添加更多重复项。
您可以用合并替换if insert else更新。
所以我会做这样的事情:
如果你在两个并发会话中调用p,你会看到:
第1场会议:
然后,会话2将被阻止:
直到会话1提交/回滚:
回到第2节:
对它放置一个独特的约束!
选择更新无济于事。如果要添加新行,则查询将不返回任何内容。所以没有什么可以锁定来停止另一个会话。
其他一些观察结果:
我不明白您为什么要在光标中加入t2。您只是在插入/更新t1。因此,当没有子t2行时,这可能会添加更多重复项。
您可以用合并替换if insert else更新。
所以我会做这样的事情:
create sequence s;
create table t (
pk int primary key,
id int unique,
c1 int
);
create or replace procedure p (
p_id int , p_v1 int
) as
begin
merge into t
using ( select p_id id, p_v1 v1 from dual ) s
on ( t.id = s.id )
when not matched then
insert ( pk, id, c1 )
values ( s.nextval, s.id, s.v1 )
when matched then
update set c1 = s.v1;
end p;
/如果你在两个并发会话中调用p,你会看到:
第1场会议:
SQL> exec p ( p_id => 1, p_v1 => 1 ); PL/SQL procedure successfully completed.
然后,会话2将被阻止:
SQL> exec p ( p_id => 1, p_v1 => 2 );
直到会话1提交/回滚:
SQL> commit; Commit complete.
回到第2节:
SQL> exec p ( p_id => 1, p_v1 => 2 );
BEGIN p ( p_id => 1, p_v1 => 2 ); END;
*
ERROR at line 1:
ORA-00001: unique constraint (CHRIS.SYS_C0043990) violated
SQL> exec p ( p_id => 1, p_v1 => 2 );
PL/SQL procedure successfully completed.
SQL> select * from t;
PK ID C1
---------- ---------- ----------
1 1 2 文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




