gpt4 book ai didi

oracle10g - Oracle 10g : What's a good, 保持记录不被连续更新的学术方法?

转载 作者:行者123 更新时间:2023-12-04 06:17:38 25 4
gpt4 key购买 nike

我们有一个名为 Contracts 的表。这些契约(Contract)记录由外部站点的用户创建,必须由内部站点的员工批准或拒绝。当契约(Contract)被拒绝时,它只是从数据库中删除。但是,当它被接受时,会生成一个名为“契约(Contract)接受”的新记录,该记录被写入自己的表中,并从契约(Contract)中存在的数据中派生而来。

问题是,两名内部员工可能最终都签订了同一份契约(Contract)。第一个用户接受并生成契约(Contract)接受记录。然后,在页面上仍然打开相同的契约(Contract)记录的情况下,第二个用户再次接受契约(Contract),创建了重复的接受记录。

解决这个问题的快速而肮脏的方法是在契约(Contract)被接受之前从数据库中检索契约(Contract),检查状态,并产生一条错误消息,说它已经被接受。这可能适用于大多数情况,但用户仍然可以在完全相同的时间单击接受按钮并通过此验证代码偷偷摸摸。

我还考虑了数据层深处的线程锁,它可以防止两个线程同时进入同一代码区域,但该应用程序存在于两个负载平衡的服务器上,因此用户可能位于不同的服务器上使这种方法无用。

我能想到的唯一方法必须存在于数据库中。从概念上讲,我想以某种方式锁定存储过程或表,以便它不能同时更新两次,但也许我在这里对 Oracle 不够了解。更新如何工作?更新请求是否以某种方式排队,以便它们不会在完全相同的时间发生?如果是这样,我可以检查 th SQL 中记录的状态并在 out 参数中返回一个值,说明它已被接受。但是如果更新请求没有排队,那么两个人仍然可以同时进入更新 sql。

寻找有关如何解决此问题的好建议。

最佳答案

一般来说,有两种方法可以解决这个问题

选项 1:悲观锁定

在这种情况下,您是悲观的,因此您在选择它时锁定表中的行。当用户查询Contracts表,他们会做类似的事情

SELECT *
FROM contracts
WHERE contract_id = <<some contract ID>>
FOR UPDATE NOWAIT;

谁先选择记录就会锁定它。无论谁第二次选择记录,都会收到 ORA-00054 错误,然后应用程序将捕获该错误并让他们知道另一个用户已经锁定了该记录。当第一个用户完成他们的工作时,他们将他们的 INSERT 发送到 Contract_Acceptance表并提交他们的事务。这会释放对 Contracts 中的行的锁 table 。

选项 2:乐观锁定

在这种情况下,您对两个用户不会发生冲突持乐观态度,因此您最初不会锁定记录。相反,您可以选择您需要的数据以及 Last_Updated_Timestamp如果列不存在,则添加到表中。就像是
SELECT <<list of columns>>, Last_Updated_Timestamp
FROM Contracts
WHERE contract_id = <<some contract ID>>

当用户接受契约(Contract)后,在做 INSERT之前进入 Contract_Acceptance ,他们发出 UPDATE关于契约(Contract)
UPDATE Contracts
SET last_updated_timestamp = systimestamp
WHERE contract_id = <<some contract ID>>
AND last_update_timestamp = <<timestamp from the initial SELECT>>;

第一个执行此更新的人将成功(该语句将更新 1 行)。这样做的第二个人将更新 0 行。应用程序检测到更新没有修改任何行的事实,并告诉第二个用户其他人已经处理了该行。

无论哪种情况

无论哪种情况,您可能都希望添加 UNIQUEContract_Acceptance 的约束 table 。这将确保 Contract_Acceptance 中只有一行任何给定的表 Contract_ID .
ALTER TABLE Contract_Acceptance
ADD CONSTRAINT unique_contract_id UNIQUE (Contract_ID)

这是第二道防线,永远不需要,但可以在应用程序没有正确实现其逻辑的情况下保护您。

关于oracle10g - Oracle 10g : What's a good, 保持记录不被连续更新的学术方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7026671/

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