加入收藏 | 设为首页 | 会员中心 | 我要投稿 东莞站长网 (https://www.0769zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长百科 > 正文

oracle – 选择和更新之间的竞争条件

发布时间:2021-02-23 12:22:11 所属栏目:站长百科 来源:网络整理
导读:我需要更新Oracle数据库中的一行,这样我就不会在基于Web的应用程序中默默地破坏来自另一个客户端的更改. 在我当前的系统中,我执行以下操作: SELECT * FROM table WHERE id=:ID AND lastmodified=:LASTMOD 如果我们开始时行仍然存在相同的最后修改日期,我们

我需要更新Oracle数据库中的一行,这样我就不会在基于Web的应用程序中默默地破坏来自另一个客户端的更改.

在我当前的系统中,我执行以下操作:

SELECT * FROM table WHERE id=:ID AND lastmodified=:LASTMOD

如果我们开始时行仍然存在相同的最后修改日期,我们知道没有人改变它,所以我们可以使用上次修改时间进行更新.

然而,当使用两个会话手动执行此操作时,我注意到如果两个客户端在大致相同的时间选择,则可能会错过选择和更新步骤之间的行已更改,因为两者都在同一秒或毫秒内发生.

最终结果是我破坏了其他用户的更改,并且没有发生任何警告.

我正在考虑使用SELECT FROM UPDATE,但显然这是一个bad idea(特别是对于网络应用程序),文章建议重新阅读(这是我上面所做的),但我仍然认为我有竞争条件的风险.

编辑:说清楚我关注时间被引用的方式.

解决方法

我假设您的UPDATE语句本身正在验证您在SELECT语句中读取的lastintified值,如ninesided所示.

如果lastmodified是DATE,那么如果在同一秒内对同一行有多个更新,则存在潜在的竞争条件,因为DATE仅具有到第二个的粒度.另一方面,如果lastmodified是TIMESTAMP,则可以发生竞争条件的窗口受到更多限制,因为TIMESTAMP将具有3到9位亚秒精度(大多数Windows机器上3个,大多数Unix上6个)机).虽然并非不可能,但是在同一毫秒或甚至相同的微秒内有两次更新并非不可能.但这并非万无一失.

您可以使用序列生成的值而不是上次修改的日期.这可以保证您不会丢失更新,因为NOCYCLE序列不会返回相同的值两次.但是如果沿着这条路走下去,你要么失去了在每一行上拥有最后更新日期的信息好处,要么在表的每一行中存储了一些额外的数据字节.根据您的应用程序,这些权衡取舍可能是值得的,或者可能会产生比解决方案更多的问题.

(编辑:东莞站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!