代码之家  ›  专栏  ›  技术社区  ›  Amit

Java-JPA-@版本注释

  •  101
  • Amit  · 技术社区  · 15 年前

    如何 @Version JPA中的注释工作?

    我找到了各种答案,摘录如下:

    jpa在实体中使用version字段来检测对同一数据存储记录的并发修改。当jpa运行时检测到有人试图同时修改同一条记录时,它会向试图最后提交的事务抛出异常。

    但我仍然不确定它是如何工作的。


    同样从以下几行:

    您应该考虑版本字段是不可变的。更改字段值的结果未定义。

    这是否意味着我们应该将version字段声明为 final ?

    5 回复  |  直到 8 年前
        1
  •  172
  •   Pascal Thivent    15 年前

    但我还是不确定它是怎么工作的?

    假设一个实体 MyEntity 有注释的 version 财产:

    @Entity
    public class MyEntity implements Serializable {    
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String name;
    
        @Version
        private Long version;
    
        //...
    }
    

    更新时,用 @Version 将递增并添加到 WHERE 子句,类似于这样:

    UPDATE MYENTITY SET ..., VERSION = VERSION + 1 WHERE ((ID = ?) AND (VERSION = ?))
    

    如果 哪里 子句无法匹配记录(因为同一实体已被另一个线程更新),则持久性提供程序将抛出 OptimisticLockException .

    这是否意味着我们应该将version字段声明为final

    不,但你可以考虑让setter受到保护,因为你不应该这么叫它。

        2
  •  23
  •   G. Demecki    10 年前

    尽管@pascal answer是完全有效的,但根据我的经验,我发现下面的代码有助于实现乐观锁定:

    @Entity
    public class MyEntity implements Serializable {    
        // ...
    
        @Version
        @Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
        private long version = 0L;
    
        // ...
    }
    

    为什么?因为:

    1. 乐观锁定 不会工作 如果字段注释为 @Version 意外设置为 null .
    2. 由于这个特殊字段不一定是对象的业务版本,为了避免误导,我更喜欢将这个字段命名为 optlock 而不是 version .

    如果应用程序使用 只有 JPA用于将数据插入数据库,因为JPA供应商将强制执行 0 对于 @version 创建时的字段。但几乎总是使用普通的sql语句(至少在单元/集成测试期间)。

        3
  •  8
  •   stefanglase    15 年前

    每次在数据库中更新实体时,版本字段将增加一个。更新数据库中实体的每个操作都将附加 WHERE version = VERSION_THAT_WAS_LOADED_FROM_DATABASE 对它的质疑。

    在检查操作中受影响的行时,jpa框架可以确保在加载和持久化实体之间没有并发修改,因为当查询的版本号在加载和持久化之间增加时,查询在数据库中找不到您的实体。

        4
  •  2
  •   uudashr    13 年前

    用于确保一次仅更新一次的版本。jpa提供者将检查版本,如果预期的版本已经增加,那么其他人已经更新了实体,因此将引发异常。

    因此,更新实体价值将更安全、更乐观。

    如果值经常更改,则可以考虑不使用version字段。例如“一个有counter字段的实体,每次访问网页时它都会增加”

        5
  •  1
  •   Pedro Borges    8 年前

    只是多加一点信息。

    jpa在幕后为您管理版本,但是当您通过 JPAUpdateClause() ,在这种情况下,需要手动将版本增量添加到查询中。

    佩德罗

    推荐文章