Java 乐观锁定与事务

Java 乐观锁定与事务,java,hibernate,optimistic-locking,Java,Hibernate,Optimistic Locking,我已经阅读了Hibernate中的@Version注释。似乎我对它的理解很肤浅,或者更准确地说,我对它的需求理解很差 情况:假设我有可重复读取隔离级别。我同时执行了两段代码: 代码1: 代码2: 问题: 在MyEntity类中没有@Version注释会产生什么结果 MyEntityclass中的@Version注释会产生什么结果 *[Main]*如果结果相同,那么使用@Version注释的优势是什么 如果不使用锁定策略,最后一次提交将“成功”。某些提供程序根据默认值实现乐观锁定,因此您不必在会

我已经阅读了Hibernate中的
@Version
注释。似乎我对它的理解很肤浅,或者更准确地说,我对它的需求理解很差

情况:假设我有可重复读取隔离级别。我同时执行了两段代码:

代码1:

代码2:

问题:

  • MyEntity
    类中没有@Version注释会产生什么结果
  • MyEntity
    class中的@Version注释会产生什么结果
  • *[Main]*如果结果相同,那么使用
    @Version
    注释的优势是什么

如果不使用锁定策略,最后一次提交将“成功”。某些提供程序根据默认值实现乐观锁定,因此您不必在会话或查询上设置任何属性

如果确实使用乐观锁定策略,第一个事务将增加版本,第二个事务将获得
OptimisticLockException

然后,您可以捕获它,刷新实体,或者重试更改


使用版本字段和不使用版本字段的区别在于,对于没有版本字段的实体,并非所有锁定策略都需要实现。因此,定义一个
@Version
字段可以使您的代码更易于移植。

因此,如果您添加一个@Version,您的表在常规列旁边将有一个名为Version的列

每次提交新值时,该值都会递增

在代码1中,您有会话。获取您的实体将有一个版本“x”

当代码2读取时,您可能也有版本“x”,所以如果代码1提交,您将有版本x+1,并且在代码2提交时,将看到版本抛出异常的差异


如果没有,您将只重写写入DB中的值code 1。

首先,如果您具有可重复读取隔离级别,则第二个事务将仅在第一次提交后执行。因此,乐观锁定没有任何用处。
当您使用乐观锁定时,db将在读取实体时记录版本,并在回写更新的实体时检查版本是否已修改。如果已修改,它将抛出OptimisticLockException,否则它将写入更新的实体并更新版本,因为许多数据库使用悲观锁定来实现可重复读取。然而,情况并非总是如此,因为存在RR的非锁定实现,您仍然可以得到OptimisticLockException。例如kostja:我想知道启用RR后如何验证版本。可能使用“在共享模式下从t锁中选择*”?
sessionFactory.openSession();
MyEntity entity = (MyEntity) session.get(MyEntity, 10);
entity.setValue(5);
session.getTransaction().commit();
sessionFactory.openSession();
MyEntity entity = (MyEntity) session.get(MyEntity, 10);
entity.setValue(10);
session.getTransaction().commit();