@Version注释是如何在JPA中工作的?
我找到了各种答案,其摘要如下:
JPA使用实体中的版本字段来检测对同一数据存储记录的并发修改。当JPA运行时检测到并发修改同一记录的尝试时,它会向试图最后提交的事务抛出一个异常。
但我还是不知道它是如何工作的。
以下几行也是如此:
您应该考虑版本字段是不可变的。更改字段值有未定义的结果。
这是否意味着我们应该将版本字段声明为final
发布于 2010-04-03 20:50:45
,但我还是不知道它是如何工作的?
假设实体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。
是否意味着我们应该将版本字段声明为最终
不,但是你可以考虑让设置者受到保护,因为你不应该这么称呼它。
发布于 2014-11-04 09:39:49
尽管@Pascal的回答是完全有效的,但根据我的经验,我发现下面的代码对于实现乐观锁定很有帮助:
@Entity
public class MyEntity implements Serializable {
// ...
@Version
@Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
private long version = 0L;
// ...
}为什么?因为:
如果用null.
version.,则
optlock,而不是version.首先,应用程序是否只使用 JPA将数据插入数据库并不重要,因为JPA供应商将在创建时为@version字段强制执行0。但是,几乎总是使用普通的SQL语句(至少在单元测试和集成测试期间)。
发布于 2010-04-03 20:50:09
每次更新数据库中的实体时,版本字段都会增加一个。更新数据库中实体的每个操作都会将WHERE version = VERSION_THAT_WAS_LOADED_FROM_DATABASE附加到其查询中。
在检查受影响的操作行时,jpa框架可以确保在加载和持久化实体之间没有并发修改,因为当实体的版本号在加载和持久化之间增加时,查询不会在数据库中找到您的实体。
https://stackoverflow.com/questions/2572566
复制相似问题