首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java @Version注释

Java @Version注释
EN

Stack Overflow用户
提问于 2010-04-03 20:28:03
回答 5查看 158.6K关注 0票数 152

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

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

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

但我还是不知道它是如何工作的。

以下几行也是如此:

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

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

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-04-03 20:50:45

,但我还是不知道它是如何工作的?

假设实体MyEntity具有带注释的version属性:

代码语言:javascript
复制
@Entity
public class MyEntity implements Serializable {    

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @Version
    private Long version;

    //...
}

在更新时,带有@Version注释的字段将被递增并添加到WHERE子句中,如下所示:

代码语言:javascript
复制
UPDATE MYENTITY SET ..., VERSION = VERSION + 1 WHERE ((ID = ?) AND (VERSION = ?))

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

是否意味着我们应该将版本字段声明为最终

不,但是你可以考虑让设置者受到保护,因为你不应该这么称呼它。

票数 224
EN

Stack Overflow用户

发布于 2014-11-04 09:39:49

尽管@Pascal的回答是完全有效的,但根据我的经验,我发现下面的代码对于实现乐观锁定很有帮助:

代码语言:javascript
复制
@Entity
public class MyEntity implements Serializable {    
    // ...

    @Version
    @Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
    private long version = 0L;

    // ...
}

为什么?因为:

如果用null.

  • As注释的字段被意外地设置为version.

,则

  1. 乐观锁定将无法工作--这个特殊字段不一定是对象的业务版本,为了避免误导性,我宁愿将这样的字段命名为optlock,而不是version.

首先,应用程序是否只使用 JPA将数据插入数据库并不重要,因为JPA供应商将在创建时为@version字段强制执行0。但是,几乎总是使用普通的SQL语句(至少在单元测试和集成测试期间)。

票数 47
EN

Stack Overflow用户

发布于 2010-04-03 20:50:09

每次更新数据库中的实体时,版本字段都会增加一个。更新数据库中实体的每个操作都会将WHERE version = VERSION_THAT_WAS_LOADED_FROM_DATABASE附加到其查询中。

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

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2572566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档