【问题标题】:Locking Mechanism on Tables表上的锁定机制
【发布时间】:2012-11-30 11:31:11
【问题描述】:

我们有一个由 Oracle 进程 P1 访问的表 TAB1(例如 SID=123)。该过程需要动态 SQL 删除,然后是提交。

由 SID=123 发起的进程 P1 除了这个 TAB1 相关操作之外还包含许多操作。

场景:

  • SID=123 处于活动状态; P1 对 TAB1 施加了行独占锁(从查询locked_object 视图中获得)。

  • 在某个时间(例如,2-3 分钟)P1 启动后,另一个 oracle 进程 P2 由 SID=124 启动(与 P1 完全相同的进程,但用于不同的数据输入集)。

  • SID=124 正在等待由 SID=123 发起的进程 P1 完成; P2 对 TAB1 施加了行排他锁(通过查询locked_object 视图获得)。

问题:

我认为 P2 的同一行级锁期望 P1 的行级锁“可以继续”。 我们是否能够手动覆盖进程 P1 对 TAB1 施加的锁定(我希望这是可能的),并在其对 TAB1 的操作结束后释放锁定?这是否有助于减少 P2 现在在 TAB1 上等待整个 P1 结束的漫长等待?

任何建议将不胜感激。如果您需要更多信息,请告诉我。

【问题讨论】:

  • 您的描述非常低级,并且侧重于当前的实现及其问题。它没有提供有关您真正想要实现的目标的任何信息。如果您在更高层次上描述您的任务并使用更多上下文信息,您更有可能获得有用的答案和好的解决方案。
  • @Codo:希望下面的描述没问题吧?由于并发的 oracle 进程,一个表被锁定,我们希望一个进程应该只等到下一个进程对表的操作处于活动状态;不要等到第一个过程完成。
  • @codo 的建议是,如果您发布您想要实现的目标,那么某人可能会提出一个您没有考虑过的完全不同的解决方案。
  • @gallardolad:不,一点也不。我宁愿考虑类似的事情:我们有一个长期运行的进程,它在数据库中进行一些维护工作,并且 - 作为该任务的一部分 - 从 OFFER 表中删除过期的报价。它直到工作结束才提交。此外,交互式用户还有另一个过程可以更新多个报价,通常需要不到一秒钟的时间。但是,当维护任务运行时,交互进程会被阻塞,直到维护任务完成。我们怎样才能避免这种情况?
  • 这两个进程是否影响同一行?我希望与一个客户相关的行集与与另一个客户相关的行集完全不同,因此我不希望两个会话尝试修改同一行。一个执行 DML 的会话会阻止另一个执行 DML 的会话的唯一原因是两个会话都试图修改同一行。如果两个会话尝试修改同一行,则无法手动解锁该行。但通常您可以设计流程以避免冲突。

标签: sql oracle plsql oracle11g locking


【解决方案1】:

锁在事务边界上释放,而不是在进程边界上。

简而言之,如果您希望 P1 立即释放锁,则 P1 必须在删除操作之后通过显式提交或回滚来结束当前事务。

当然,结束事务也会提交/回滚在前一次提交/回滚之后在同一会话中执行的其他操作。如果这是一个问题,您必须重新考虑业务逻辑。

等等,你写的是“动态 SQL 删除后提交”……如果你的意思是“立即跟随”,那么行独占锁已经被立即释放了。

【讨论】:

    【解决方案2】:

    我实际上已经“避免了这种情况”,这意味着“这个答案不是解决方案”。
    我为避免这种情况所做的一切:

    1. 在 TAB1 中再添加一列,为每个进程放置一个唯一标识号。
    2. 使用此列仅删除与该特定进程对应的行。 我相信这避免了进程 P1 和 P2 等待同一行。

    感谢@Codo、@a_horse_with_no_name、@Ben、@Justin Cave 和@colemar 在尝试根据上下文美化问题和支持方面提供的所有帮助。

    @Justin Cave:我一直在考虑与您提出的相同解决方案,但如果我昨天看到这个,我就不必浪费时间到现在了。无论如何,非常感谢您的支持。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      相关资源
      最近更新 更多