- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们有一个名为 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;
Contract_Acceptance
表并提交他们的事务。这会释放对
Contracts
中的行的锁 table 。
Last_Updated_Timestamp
如果列不存在,则添加到表中。就像是
SELECT <<list of columns>>, Last_Updated_Timestamp
FROM Contracts
WHERE contract_id = <<some contract ID>>
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>>;
UNIQUE
对
Contract_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/
我是一名优秀的程序员,十分优秀!