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

标签 oracle10g simultaneous

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

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

解决这个问题的快速而肮脏的方法是在合约被接受之前从数据库检索合约,检查状态,并生成一条错误消息,表明它已被接受。这可能适用于大多数情况,但用户仍然可以同时单击“接受”按钮并偷偷通过此验证代码。

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

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

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

最佳答案

首先,如果每个契约(Contract)只能有一个契约(Contract)接受,那么契约(Contract)接受应该将契约(Contract) ID 作为其自己的主(或唯一)键:这将使重复成为不可能。

其次,为了防止第二个用户在第一个用户接受契约(Contract)时尝试接受契约(Contract),您可以使接受过程锁定契约(Contract)行:

select ...
from Contract
where contract_id = :the_contract
for update nowait;

insert into Contract_Acceptance ...

第二个用户的接受尝试将失败并出现异常:

ORA-00054: resource busy and acquire with nowait specified

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

相关文章:

sql - 选择具有条件的行之一

python - 如何在 python 中同时运行两个 turtle ?

variables - Mathematica- 在给定随机变量和设置方程时求解

sql - 表锁会加速 Oracle 10g 企业版中的更新语句吗?

oracle - 如何配置我的 Oracle tnsnames 文件位置?

apache-spark - 如何使用ojdbc14.jar在spark-sql-2.4.1v中将日期/时间戳作为lowerBound/upperBound传递?

大型数据库表的 sql 优化器

javascript - 在javascript中同时触发/触发多个函数时如何设置函数执行顺序?

iOS:同时录制和播放的示例代码