我为它实现了一个服务entity object
,它使用了 pure jpa
,我使用了spring
,所以spring xml config
配置hibernate
为一个jpa
impl。我正在使用spring
数据进行crud
操作。但是在我们的系统中,我们的entity
对象被多次拉取/更新concurrency
,并且数据存在高竞争()。从我们在许多地方的代码中,很多classes
只是inject
服务 bean 和调用getEntity
方法来获取一个实体,之后他们更改实体(据我的理解,这是分离的,但在同一个线程中,所以 em 对象应该与我的知识相同)所以实体需要一段时间才能回到服务进行更新,他们调用save()
服务的方法来保存实体。Save()
方法只不过是调用merge()
粗加工操作。它是带有@Transactional
注释的事务性的。这里出现了一个问题,当有人拉动一个实体对象并且在更改它时其他人可能会拉动并更改它并将其保存回来,所以我的实体读取是脏的,如果保存它,我将覆盖已经更新的实体。问题是我们正在改变服务之外的实体并调用保存。这里 spring 数据存储库类是 DAO 层。
Optimistic lock
是一种解决方案,但由于某些原因我们不喜欢它,所以它对我们不起作用。我在想pessimistic lock
。例如,当我通过锁定获取要更新的实体时,然后在不同位置的其他地方更改它并回调(entity
已经锁定更新!)它是否有效?我不确定它是否仍然EntityManager
反对我用来拉实体的地方。如果它在那里,则需要很长时间才能通过这些“智能”逻辑,然后才能对其进行更新和解锁。
这是该场景的简单示例代码:
class SomeEntity {
Long id;
String field1;
String field2;
String field3;
String field4;
String field5;
String field6;
String field7;
//getters and setters, column annotations
}
class SomeEntityServiceImple implemenet SomeEntityService{
@Transactional
save(SomeEntity se){
//call to spring data's merge() method
}
get(Long id){
//call to spring data's findOne()
}
}
//this class might be spring bean, might not be. If it is not I will get SomeEntityService bean from shared appContext
class SomeCrazyClass{
@Autowired
SomeEntityService service;
someMethod(){
SomeEntity e = service.get(1L);
//do tons of logic here, change entity object, call some another methods and again, takes 3 seond
service.save(e); //Probably detached and someone updated this object, probably overriding it.
}
}
}
在这里,我不能tons of logic
在服务层中移动它,它非常具体,这种不同的逻辑存在于数百个地方。
那么有什么办法可以解决并至少对这种情况应用悲观锁定?