有什么方法可以知道 JPA 中何时出现乐观并发问题以及如何解决?
问题描述: 在我的项目中,当我想更新数据库中的数据但其他用户正在使用它时。在那种情况下,我想获得 DB_STATUS 或异常,这意味着“其他用户正在使用..”。所以我想跳过更新数据库。
持久性提供程序使用该Version
字段或属性来执行乐观锁定。它由持久性提供者在对实体实例执行生命周期操作的过程中访问和/或设置。如果实体具有映射为 的属性或字段,则会自动启用乐观锁定Version mapping
:
version
在您的实体中定义一个属性:
@Version
private long version;
以及实体的数据库表中的相应version
字段。
假设您已经加载了一个 id=123 和 version=1 的实体。一旦交易完成,实体状态将变为detached
状态。
您对处于状态的实体进行了更改detached
。您可以使用EntityManager.merge()
. 由于它是一个detached
实例,Hibernate 将发出类似于此的 SQL 更新:
update ENTITY set ... , VERSION=2 where ID=123 and VERSION=1
如果另一个应用程序事务在加载后更新了同一个 ENTITY,则 VERSION 列将不包含值 1,并且不会更新该行。您将收到一个OptimisticLockException
并且该事务将被标记为回滚。您可以捕获异常并通知用户有关过时的数据。
合并操作version
在实体被合并时检查属性,OptimisticLockException
如果发现被合并的对象是实体的旧副本——即实体在实体分离后已被更新,则抛出一个。