问题描述
嗨,汤姆
我们有一个存储的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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle RAC ASM 磁盘组满了,无法扩容怎么在线处理?
Lucifer三思而后行
937次阅读
2025-03-17 11:33:53
Oracle DataGuard高可用性解决方案详解
孙莹
397次阅读
2025-03-26 23:27:33
墨天轮个人数说知识点合集
JiekeXu
340次阅读
2025-04-01 15:56:03
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
331次阅读
2025-04-08 09:12:48
Oracle SQL 执行计划分析与优化指南
Digital Observer
300次阅读
2025-04-01 11:08:44
风口浪尖!诚通证券扩容采购Oracle 793万...
Roger的数据库专栏
281次阅读
2025-03-24 09:42:53
Oracle 19c RAC更换IP实战,运维必看!
szrsu
276次阅读
2025-04-08 23:57:08
切换Oracle归档路径后,不能正常删除原归档路径上的归档文件
dbaking
276次阅读
2025-03-19 14:41:51
oracle定时任务常用攻略
virvle
268次阅读
2025-03-25 16:05:19
Oracle NetSuite 客户说|健合(H&H)集团部署 Oracle NetSuite,全面提升全球运营效率
甲骨文中国
254次阅读
2025-03-28 15:00:30