@Version注释
@Version
注释如何在JPA中工作?
我找到了各种答案,其摘录如下:
JPA在您的实体中使用版本字段来检测对同一数据存储区记录的并发修改。 当JPA运行时检测到试图同时修改同一记录时,它会向尝试提交最后的事务抛出异常。
但我仍然不确定它是如何工作的。
同样来自以下几行:
您应该考虑版本字段不可变。 更改字段值有未定义的结果。
这是否意味着我们应该将我们的版本字段声明为final
?
但我仍然不确定它是如何工作的?
假设实体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 = ?))
如果WHERE
子句无法匹配记录(因为同一个实体已被另一个线程更新),那么持久性提供者将抛出一个OptimisticLockException
。
这是否意味着我们应该将我们的版本字段声明为final
不,但你可以考虑让制定者保护起来,因为你不应该叫它。
尽管@Pascal答案是完全有效的,但从我的经验来看,我发现下面的代码有助于实现乐观锁定:
@Entity
public class MyEntity implements Serializable {
// ...
@Version
@Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
private long version = 0L;
// ...
}
为什么? 因为:
@Version
注释的@Version
被意外设置为null
乐观锁定将不起作用 。 optlock
而不是version
。 如果应用程序仅使用JPA将数据插入数据库,则第一点并不重要,因为JPA供应商将在创建时为@version
字段强制执行0
。 但几乎总是普通的SQL语句也在使用中(至少在单元/集成测试期间)。
每次在数据库中更新实体时,版本字段都会增加1。 更新数据库中的实体的每个操作都将在其查询中附加WHERE version = VERSION_THAT_WAS_LOADED_FROM_DATABASE
。
在检查受影响的操作行时,jpa框架可以确保在加载和持久化实体之间没有并发修改,因为在加载和保持之间版本号已经增加时,查询在数据库中找不到实体。
链接地址: http://www.djcxy.com/p/89587.html上一篇: @Version annotation