【问题标题】:How does when an entity with @Version annotatted field or property, optimistic lock enables automatically?当带有@Version 注释字段或属性的实体自动启用乐观锁时如何?
【发布时间】:2016-03-29 12:55:02
【问题描述】:

最近一直在研究数据库事务,一篇文章引用如下

JPA 通过@Version 注释自动支持行版本控制。当您拥有带有@Version 注释字段或属性的实体时,将自动启用乐观锁定。

我的理解是数据库隔离级别策略是使用不同的锁来维护的,比如

  1. 读取未提交:使用独占写入锁实现
  2. 已提交读:使用共享读锁和独占写锁实现。

等等。因此,事务隔离是通过不同的锁定实现的,我猜是使用悲观锁定。

我的问题是,当一个字段被声明为 @Version 注释时,它是否会覆盖底层默认隔离级别并发生乐观锁定?

【问题讨论】:

    标签: java mysql jpa optimistic-locking pessimistic-locking


    【解决方案1】:

    不,它们是不同的东西。默认情况下,隔离级别配置为read-commited,因此在事务提交之前无法读取任何更改。

    如果你决定通过@Version来使用乐观锁,那么你根本没有改变隔离级别,但是假设你想使用read-commited隔离级别,因为我认为使用@没有意义987654324@ 或 read-serialized 当您使用乐观锁定时,但您可以。

    创建事务时定义隔离级别,通常指定事务的只读模式、隔离级别、传播模式和名称。

    乐观锁由 ORM 基础设施控制,在持久化时注意对象的正确编号版本。所以,它们是不同的东西。

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      不,您不能使用 JPA 的乐观锁定覆盖底层数据库的隔离级别

      如果你能以某种方式做到这一点,那么这样做就不好了。

      大多数数据库默认采用 READ_COMMITED 隔离级别。

      READ_COMMITED 隔离级别下考虑以下场景。

      • 两个经理加载一个Product 实体
      • 他们俩都决定提高价格然后保存。
      • 一个价格更新在另一个之前提交。
      • 因此,一位经理的价格将被另一位经理的价格覆盖,而经理却不知道这一点。

      虽然这种情况是微不足道的,但这种事情可能会发生在不平凡的情况下。

      使用乐观锁定和数据库的默认隔离级别可以避免这种意外情况。

      希望这会有所帮助。

      【讨论】:

      • tharindu_DG 在我的情况下,我使用的是默认隔离级别是可重复读取的 mysql 数据库。所以除了隔离级别的可重复读取,我可以根据我的要求使用乐观锁定或悲观锁定,对吧?
      • repeatable reads 是比read committed 更高的隔离级别,因为它不仅会阻塞写入,还会阻塞读取,以避免non-repeatable reads 问题。无论如何,我猜它与乐观锁定兼容。
      猜你喜欢
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      • 2019-03-07
      • 1970-01-01
      • 1970-01-01
      • 2010-11-28
      • 2017-11-13
      • 2017-12-22
      相关资源
      最近更新 更多