gpt4 book ai didi

java - 我可以在 Oracle 中进行原子 MERGE 吗?

转载 作者:太空狗 更新时间:2023-10-29 22:39:17 25 4
gpt4 key购买 nike

我有几个在单个 WebLogic 集群中运行的 J2EE 应用实例。

在某些时候,这些应用程序会执行 MERGE 以将记录插入或更新到后端 Oracle 数据库中。 MERGE 检查是否存在具有指定主键的行。如果它在那里,请更新。如果没有,插入。

现在假设两个应用程序实例想要插入或更新主键 = 100 的行。假设该行不存在。在合并的“检查”阶段,他们都看到行不存在,因此他们都尝试插入。然后我得到一个唯一的键约束违规。

我的问题是:Oracle 中是否有原子 MERGE?我正在寻找与 PL/SQL 中的 INSERT ... FOR UPDATE 具有类似效果的东西,只是我只能从我的应用程序中执行 SQL。

编辑:我不清楚。我正在使用 MERGE 语句,但仍然出现此错误。问题是,只有“修改”部分是原子的,而不是整个合并。

最佳答案

这不是 MERGE 本身的问题。相反,问题在于您的应用程序。考虑这个存储过程:

create or replace procedure upsert_t23 
( p_id in t23.id%type
, p_name in t23.name%type )
is
cursor c is
select null
from t23
where id = p_id;
dummy varchar2(1);
begin
open c;
fetch c into dummy;
if c%notfound then
insert into t23
values (p_id, p_name);
else
update t23
set name = p_name
where id = p_id;
end if;
end;

因此,这是 T23 上 MERGE 的 PL/SQL 等价物。如果两个 session 同时调用它会怎样?

SSN1>  exec upsert_t23(100, 'FOX IN SOCKS')

SSN2> exec upsert_t23(100, 'MR KNOX')

SSN1先到那里,找不到匹配的记录并插入一条记录。 SSN2 第二个到达那里,但在 SSN1 提交之前,找不到记录,插入记录并挂起,因为 SSN1 在唯一 inode 上锁定了 100。当 SSN1 提交时,SSN2 将引发 DUP_VAL_ON_INDEX 违规。

MERGE 语句的工作方式完全相同。两个 session 都将检查 on (t23.id = 100),找不到它并进入 INSERT 分支。第一个 session 将成功,第二个 session 将抛出 ORA-00001。

处理此问题的一种方法是引入悲观锁定。在 UPSERT_T23 过程开始时,我们锁定表:

...
lock table t23 in row shared mode nowait;
open c;
...

现在,SSN1 到达,获取锁并像以前一样进行。当 SSN2 到达时它无法获得锁,因此它立即失败。这让第二个用户感到沮丧,但至少他们没有挂起,而且他们知道其他人正在处理同一条记录。

INSERT 没有等同于 SELECT ... FOR UPDATE 的语法,因为没有什么可以选择的。因此 MERGE 也没有这样的语法。您需要做的是在发出 MERGE 的程序单元中包含 LOCK TABLE 语句。这对您是否可行取决于您使用的框架。

关于java - 我可以在 Oracle 中进行原子 MERGE 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4226830/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com