JPA中的SELECT查询和乐观锁定

3
我在某些对象被锁定时遇到了一个与SELECT查询相关的问题。例如:
我在Table 1中的一个对象上设置了OPTIMISTIC_FORCE_INCREMENT锁,同时有另一个包含对Table 2的SELECT查询的事务。然而,Table 2没有任何将其连接到Table 1的数据库对象(外键或其他类型的约束)。但是当发生第二个SELECT查询时,会抛出OptimisticLockException异常。
有人知道为什么会发生这种情况吗?
1个回答

1
很不可能仅通过选择查询抛出乐观锁异常(OLE)。我假设您确实在某个地方进行了更新。
当使用乐观锁定时,通常实体具有版本列(由@Version注释标记)。当要将实体与数据库同步时,OLE通常会发生。例如(下面的每个步骤都是1个单独的数据库事务):
1. Bob从数据库获取“用户”实体。到目前为止,该用户的版本为1。然后将此用户实体传递给视图表单/用户界面进行编辑。 2. 在Bob完成编辑之前,Sue也从数据库中获取相同的用户,进行更改并保存她的编辑,因此将版本标签增加到2。 3. 当Bob尝试保存更改时,JPA注意到用户实体的版本不再是1,他的用户版本已过期,然后抛出OLE。
通常最好的方法是捕获OLE,并向用户呈现一条消息,大致如下:“嘿,有人编辑了相同的实体并首先保存了。您要覆盖/合并/放弃自己的更改吗?”

1
是的,就像我之前写的那样,它发生在选择时,没有进行更新、删除或更改,并且它发生在与锁定实体完全不同的实体上。 - pfulop
你的实体是否有一个 @Version 列? - gerrytan
我锁定的那一个,是的。 - pfulop
但是为什么在SELECT查询中会发生乐观锁定呢?我认为它应该在进行更新的事务中抛出。 - Serginho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接