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

2024-04-10

我需要以一种不会默默破坏基于 Web 的应用程序中另一个客户端的更改的方式更新 Oracle 数据库中的行。

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

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

如果该行仍然存在,并且在我们开始时具有相同的上次修改日期,我们就知道没有人更改它,因此我们可以使用上次修改时间进行更新。

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

最终结果是我破坏了其他用户的更改,并且没有任何警告表明发生了这种情况。

我正在考虑使用 SELECT FROM UPDATE 但显然这是一个bad idea http://www.dba-oracle.com/t_select_for_update.htm(特别是对于网络应用程序),该文章建议重新阅读(这就是我上面所做的),但我仍然认为我面临竞争条件的风险。

Edit:明确表示我担心时间的引用方式。


我假设你的UPDATE声明本身正在验证lastmodified您在中读到的值SELECT正如九边所暗示的那样。

If lastmodified is a DATE,那么如果自某个时刻以来同一秒内对同一行进行多次更新,则存在潜在的竞争条件DATE仅具有秒级的粒度。如果lastmodified is a TIMESTAMP,另一方面,竞争条件可能发生的窗口要有限得多,因为TIMESTAMP将具有 3 到 9 位的亚秒精度(在大多数 Windows 机器上为 3 位,在大多数 Unix 机器上为 6 位)。在同一毫秒甚至同一微秒内进行两次更新的可能性很小,但并非不可能。但这并不是绝对正确的。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

选择和更新之间的竞争条件 的相关文章

  • 最新的 Open JDK 8 JAXB 库无法解组具有包含换行符的属性的对象

    我在 Ubuntu 16 04 上使用 Java 最近我升级到使用 oracle java8 installer 包 包版本 8u161 1 webupd8 0 安装的 Open JDK java 版本 1 8 0 161 自从进行此升级以
  • 如何通过 sql plus 从命令行发出单个命令?

    使用 SQL Plus 您可以运行script从命令行使用 运算符 如下所示 c gt sqlplus username password databasename c my script sql 但是是否可以只运行一个单一命令使用类似的语
  • Oracle 中四舍五入到特定有效数字位数

    oracle 是否有舍入函数可以四舍五入到特定数量的有效数字 例如 将 1278 舍入到 1300 四舍五入到两位有效数字 Try ROUND x d FLOOR LOG 10 x 1 where d是有效位数 x是要四舍五入的值 Exam
  • Oracle SQL Regexp_replace 匹配

    这是我需要完成的一个时髦的匹配 A5 1 9 11 2 需要成为 A05 01 09 11 02 DOT 部分的数量从没有到很多不等 字母 A 将始终存在并且始终为 1 个字符 我想使用 regexp replace 函数 以便将其用作排序
  • Python 在 macOS 上“DPI-1047 无法找到 dlopen(libclntsh.dylib)”

    我收到以下错误 cx Oracle DatabaseError DPI 1047 64 bit Oracle Client library cannot be loaded dlopen libclntsh dylib 1 image no
  • 从数字字符串生成行

    我有一个 Oracle 18c 表 其中包含如下字符串 select 0 5 0 10 10 11 18 30 0 33 54 50 10 33 54 60 10 43 54 as multipart lines There are mor
  • iPhone:通过互联网连接到数据库?

    我一直在和某人谈论 iPhone 开发合同工作的可能性 目前我真正知道的是 有一家公司想要制作一款 iPhone 应用程序 该应用程序将访问其内部数据库 我不确定数据库类型是什么 Oracle MySQL 等 我想知道数据库类型是 Orac
  • 如何 UPSERT(更新或插入表?)

    UPSERT 操作更新或插入表中的行 具体取决于表是否已有与数据匹配的行 if table t has a row exists that has key X update t set mystuff where mykey X else
  • Oracle 中的重复行

    如何防止在选择查询中选择重复的行 我有一个包含以下字段的表 name type user1 user2 user3 date 我的查询要求我仅在用户在前端输入的时间为特定用户选择数据 假设用户输入 1 那么选择查询应仅检索 user1 的数
  • 通过 SQL Developer 连接时出现 ora-12505 错误

    我正在尝试使用 SQL Developer 远程连接到 Oracle 12c 数据库 为了从另一台计算机进行远程连接 我在运行 Oracle 的计算机上在 Windows 7 防火墙中打开了一个端口 该部分有效 但现在由于此错误 ORA 1
  • 当所有子记录满足条件时仅选择父记录

    我有两个表 A 和 B 当所有子项 表 B 中 满足条件时 我只需要父项 A 的行 如果 B 中的一行不符合条件 那么我不需要父 A 的行 我想我需要在这里使用存在 但不展示如何使用 以下是数据表 Table A Primary Key L
  • Oracle 日期索引很慢。没有它查询速度快 300 倍

    我有一个 Oracle 查询 如下所示 运行时间为 10 分钟或更长时间 select r range text as duration range nvl count c call duration 0 as calls nvl SUM
  • 如何在“Where”子句之前写“Order By”子句

    我想写一个ORDER BY我之前的子句WHERE条件 因为我需要将结果截断为 10 但我需要首先按字母顺序对它们进行排序 我知道你不能把ORDER BY before WHERE那我该怎么办呢 我需要做类似以下的事情 SELECT FROM
  • 选择不同的字段和行号只是为了显示 ID 号会产生重复的数据

    我有一个表应用程序 它有 10 列 类别是一列 并且该列有重复值 为了获得不同的值 我有一个查询 SELECT distinct CATEGORY as CategoryName FROM APPLICATION where applica
  • ORA-00972 标识符别名列名太长

    我有一个查询 例如 SELECT column as averyveryveryverylongalias more than 30 characters FROM Table name 它返回错误ORA 00972 标识符太长 有什么技巧
  • 如何将 SELECT...INTO 与 JOIN 一起使用?

    我有以下示例代码 DECLARE myRow table rowtype myVar table2 column type BEGIN SELECT table col1 table col3 table col4 table2 colum
  • 如何找到与日期范围最重叠的时间段

    假设您有一个包含标识符 开始时间和结束时间的表 这些开始和结束时间可以是任意时间长度 开始时间始终早于结束时间 假设没有空值 什么样的查询会告诉我最 流行 的时间 即每行中的两个范围与大多数其他行重叠的位置 它的实际应用是它是一个记录用户登
  • SQL SELECT 在父亲 ID 组织树中查找循环引用?

    带有循环引用的 乐趣 假设我有一个表 ELEMENTS 其中包含元素的层次结构 由父 ID 建模 对于根来说 父亲 ID 字段为空 所有其他记录都有一个非空父 id 和 自动排序的 主键 ID 的父元素 例如 使用 SELECT FROM
  • 从集合类型 Oracle 12c 插入表 - ORA-00902: 无效数据类型

    我正在使用 Oracle 12 1 我以为我可以查询 12c 中的表类型 当我尝试执行此包时 我收到错误 ORA 00902 无效数据类型 我什至尝试使用强制转换多重集 但仍然出现同样的错误 我知道我们可以在数据库级别创建对象然后查询 但我
  • 超时后如何重新建立 JDBC 连接?

    我有一个长时间运行的方法 它通过 EntityManager TopLink Essentials 执行大量本机 SQL 查询 每个查询只需要几毫秒即可运行 但查询数量却有数千个 这发生在单个 EJB 事务内 15 分钟后 数据库关闭连接

随机推荐