gpt4 book ai didi

oracle - LockModeType Jpa 的区别

转载 作者:行者123 更新时间:2023-12-03 15:20:17 27 4
gpt4 key购买 nike

我对 JPA 中 LockModeTypes 的工作感到困惑:

  • LockModeType.Optimistic
  • 它在提交时增加版本。
  • 这里的问题是:如果我的实体中有 version 列,并且如果我没有指定此锁定模式,那么它的工作方式也类似,那么它的用途是什么?
  • LockModeType.OPTIMISTIC_FORCE_INCREMENT
  • 即使实体没有更新,它也会增加版本列。
  • 但是如果在提交此事务之前任何其他进程更新了同一行,它有什么用?这笔交易无论如何都会失败。那么这个LockModeType有什么用? .
  • LockModeType.PESSIMISTIC_READ
  • 此锁定模式发出 select for update nowait (如果没有指定提示超时)..
  • 所以基本上这意味着在这个事务被提交之前没有其他事务可以更新这个行,那么它基本上是一个写锁,为什么它被命名为 Read锁?
  • LockModeType.PESSIMISTIC_WRITE
  • 这种锁定模式也会发出 select for update nowait (如果没有指定提示超时)。
  • 这里的问题是这个锁模式和LockModeType.PESSIMISTIC_READ有什么区别正如我所见,两者都触发了相同的查询?
  • LockModeType.PESSIMISTIC_FORCE_INCREMENT
  • 这是select for update nowait (如果没有指定提示超时)并且还会增加版本号。
  • 我完全没有使用它。
  • 如果 for update no wait,为什么需要版本增量在那儿?
  • 最佳答案

    我首先要区分乐观锁和悲观锁,因为它们的底层机制不同。
    乐观锁完全由 JPA 控制,只需要在 DB 表中添加额外的版本列。它完全独立于用于存储关系数据的底层数据库引擎。
    另一方面,悲观锁定使用底层数据库提供的锁定机制来锁定表中的现有记录。 JPA 需要知道如何触发这些锁,而某些数据库不支持或仅部分支持。
    现在到锁类型列表:

  • LockModeType.Optimistic
  • 如果实体指定了版本字段,则这是默认值。对于没有版本列的实体,不能保证使用这种类型的锁适用于任何 JPA 实现。这种模式通常被忽略,如 ObjectDB 所述.在我看来,它的存在只是为了让您可以动态计算锁模式并进一步传递它,即使锁最终是乐观的。虽然不是很可能的用例,但提供一个选项来引用甚至默认值总是很好的 API 设计。

  • 例子:
       `LockModeType lockMode = resolveLockMode();
    A a = em.find(A.class, 1, lockMode);`
  • LockModeType.OPTIMISTIC_FORCE_INCREMENT
  • 这是一个很少使用的选项。但如果你想锁定另一个实体引用这个实体,这可能是合理的。换句话说,即使实体没有被修改,您也希望锁定它的工作,但其他实体可能会被修改与该实体相关。
  • 示例:我们有实体 Book 和 Shelf。可以将书添加到书架,但书没有对其书架的任何引用。锁定将一本书移到书架的 Action 是合理的,这样一本书在本次交易结束之前不会在另一个书架上结束(由于另一笔交易)。要锁定此操作,仅锁定当前书架实体是不够的,因为该书还不必在书架上。锁定所有目标书架也是没有意义的,因为它们在不同的交易中可能会有所不同。唯一有意义的是锁定书实体本身,即使在我们的例子中它没有被改变(它没有对其书架的引用)。
  • LockModeType.PESSIMISTIC_READ
  • 这种模式类似于LockModeType.PESSIMISTIC_WRITE ,但有一点不同:在某个事务在同一实体上设置写锁之前,它不应该阻止读取实体。它还允许其他事务使用 LockModeType.PESSIMISTIC_READ 锁定. WRITE 和 READ 锁之间的区别很好解释 here (ObjectDB)here (OpenJPA) .如果一个实体已经被另一个事务锁定,任何锁定它的尝试都会引发异常。可以将此行为修改为在抛出异常并回滚事务之前等待一段时间释放锁。为此,请指定 javax.persistence.lock.timeout提示在抛出异常之前等待的毫秒数。如 Java EE tutorial 中所述,有多种方法可以在多个级别上执行此操作。 .
  • LockModeType.PESSIMISTIC_WRITE
  • 这是LockModeType.PESSIMISTIC_READ的更强版本.当WRITE锁到位,JPA 在数据库的帮助下将阻止任何其他事务读取实体,而不仅仅是像 READ 那样写入锁。
  • 没有规定如何在 JPA 提供程序中与底层 DB 合作实现这一点。在您使用 Oracle 的情况下,我会说 Oracle 没有提供接近于 READ 的东西。锁。 SELECT...FOR UPDATE真的是一个WRITE锁。这可能是 hibernate 中的一个错误,或者只是一个决定,而不是实现自定义的“更软”READ锁,“更难”WRITE使用锁代替。这主要不会破坏一致性,但不包含 READ 的所有规则。锁。您可以使用 READ 运行一些简单的测试。锁和长时间运行的事务,以确定是否有更多事务能够获取READ锁定同一个实体。这应该是可能的,而不是 WRITE锁。
  • LockModeType.PESSIMISTIC_FORCE_INCREMENT
  • 这是另一种很少使用的锁定模式。但是,它是您需要组合 PESSIMISTIC 的一个选项。和 OPTIMISTIC机制。使用普通 PESSIMISTIC_WRITE在以下情况下会失败:
  • 事务 A 使用乐观锁定并读取实体 E
  • 事务 B 获取实体 E 的 WRITE 锁
  • 事务 B 提交并释放 E
  • 的锁
  • 事务 A 更新 E 并提交

  • 在步骤 4 中,如果 version 列没有被事务 B 增加,则没有什么可以阻止 A 覆盖 B 的更改。锁定模式 LockModeType.PESSIMISTIC_FORCE_INCREMENT将强制事务 B 更新版本号并导致事务 A 失败并返回 OptimisticLockException ,即使 B 使用悲观锁定。
  • LockModeType.NONE
  • 如果实体不提供版本字段,则这是默认设置。这意味着未启用锁定冲突将尽最大努力解决并且不会被检测到。这是在事务之外允许的唯一锁定模式
  • 关于oracle - LockModeType Jpa 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33062635/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com