【问题标题】:Oracle for Update SKIP LOCKED and Left JoinOracle for Update SKIP LOCKED 和 Left Join
【发布时间】:2021-12-05 14:00:11
【问题描述】:

在我正在进行数据库迁移的那一刻,我需要将下面的查询从 Sybase 迁移到 Oracle,但我真的不知道如何“翻译”3 READPAST。 有人可以帮我吗?

SELECT CC.COURS_CLIENT_ID
       , CC.TYPE_CLIENT
       , ISNULL( RT1.CODE , RV.CODE) AS CODE 
FROM TB_CLIENT CC READPAST
       LEFT JOIN TB_TRANSCO RT1 READPAST 
           ON CC.INST_ID = RT1.CONTRAT_ID AND RT1.TRANSCO_ID = 111
       LEFT JOIN TB_VAL RV READPAST
            ON CC.INST_ID = RV.VAL_ID AND RV.TRANSCO_ID = 111
       LEFT JOIN TB_CONT RC 
           ON RC.CONTRIB_ID = CC.CONTRIB_ID
WHERE CC.TRT_ID = 123 
AND CC.STATUT = 'STD'
ORDER BY CC.COURS_CLIENT_ID,RT1.CRE_DT

【问题讨论】:

  • 您是使用 select 来检索行还是作为 select for update 的一部分?

标签: oracle skip locked


【解决方案1】:

根据 Sybase 的定义

readpast 允许对 DOL 锁定表执行删除命令 不会被其他任务持有的不兼容锁阻塞。在 数据行锁定表,readpast 跳过共享的所有行, 更新,或者排他锁被另一个任务持有。

在数据页锁定的表上,readpast 会跳过共享的所有页, 更新,或者排他锁被另一个任务持有。

在您的情况下,如果正在执行选择以更新某些记录,您可以使用 select for update 和选项 skip locked

SELECT CC.COURS_CLIENT_ID, CC.TYPE_CLIENT, ISNULL( RT1.CODE , RV.CODE) AS CODE FROM TB_CLIENT CC 
       LEFT JOIN TB_TRANSCO RT1 ON CC.INST_ID = RT1.CONTRAT_ID AND RT1.TRANSCO_ID = 111
       LEFT JOIN TB_VAL RV ON CC.INST_ID = RV.VAL_ID AND RV.TRANSCO_ID = 111
       LEFT JOIN TB_CONT RC ON RC.CONTRIB_ID = CC.CONTRIB_ID
            WHERE CC.TRT_ID = 123 AND CC.STATUT = 'STD'
           FOR UPDATE SKIP LOCKED; 

但是,select for update skipped locked 在高并发环境中对防止锁定错误很有用,但是如果更改的值依赖于行中的另一个列值,则会面临逻辑损坏的风险。一般来说,重读策略更好,在更新之前重新读取每一行,以确保它自初始读取以来没有改变。

【讨论】:

  • 谢谢@Roberto Hernandez,但我不确定这种方法是否相同,因为我们在查询中有 3 个 READPAST。我正在尝试使用游标来遍历值,这对于 where 和内部连接语句非常简单,但使用左连接语句并不那么简单。
  • READPAST 允许您在 Sybase 中进行脏读。 Oracle 不允许脏读。如果您正在更新,Oracle 将在您开始查询时使用行的 SCN。这意味着当您启动更新查询时,选择将检索在同一时刻提交的行
  • 如果您使用Oracle中的过程,您可以发布代码。
猜你喜欢
  • 2011-04-25
  • 1970-01-01
  • 2016-01-29
  • 2019-10-19
  • 2019-04-16
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多