我想用@Version
进行乐观并发控制,使用JPA & Hibernate。Hibernate/JPA版本并发控制和DTO /更改命令模式
我知道它是如何工作在两个并行交易的典型场景。我也知道,如果我在表单和实体之间有1:1映射的CRUD,我可以通过version
作为隐藏字段,并用它来防止用户同时修改。
什么更有趣的情况下,它使用的DTO或更改命令模式?在这种情况下是否可以使用@Version
以及如何?
让我给你举个例子。现在,让我们说两个用户为此打开GUI,进行一些修改并保存更改(不同时,因此事务不重叠)。
如果我绕过整个实体,第二次交易将失败:
@Transactional
public void updateMyEntity(MyEntity newState) {
entityManager.merge(newState);
}
这很好,但我不喜欢传球的实体无处不在的想法,有时会使用DTO的,变化的命令等。
为了简单改变命令是一个地图,最终在通话中使用这样的一些服务:
@Transactional
public void updateMyEntity(int entityId, int version, Map<String, Object> changes) {
MyEntity instance = loadEntity(entityId);
for(String field : changes.keySey()) {
setWithReflection(instance, field, changes.get(field));
}
// version is unused - can I use it somehow?
}
显然,如果两个用户打开我的GUI两种,做出改变,并且一个接一个地执行,在这种情况下,两个改变都将被应用,最后一个将会“获胜”。我想这个场景也检测到并发修改(第二个用户应该会得到一个异常)。
我该如何实现它?