я реализовал услугу для entity object
и использует чистый jpa
, я использовал spring
, поэтому в spring xml config
настроен hibernate
как jpa
осущ. Я использую spring
данных для crud
операций. Но в нашей системе находится наш entity
объект вытащил/обновил много раз, и есть высокая конкуренция (concurrency
). Из нашего кода во многих местах много classes
только inject
сервисный компонент и вызов метода getEntity
для получения сущности, после него они меняют сущность (которая отделяется как мое понимание, но в том же потоке, поэтому объект em должен быть таким же, как в мои знания), поэтому требуется некоторое время, когда объект возвращается к обновляемому сервису, они вызывают метод службы save()
для сохранения объекта. Save()
метод - это всего лишь звонки merge()
crud operation. это транзакция с аннотацией @Transactional
. Здесь возникает проблема, когда кто-то тянет объект сущности, и, изменяя его, кто-то другой может потянуть и изменить его и сохранить его обратно, поэтому мой сущность прочитана, и если сохранить ее, я переопределю уже обновленный объект. Проблема заключается в том, что мы меняем сущность вне службы и вызываем ее обратно. Здесь весовые классы хранилищ данных - это слой DAO.JPA слияния() лучшая практика
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
внутри слоя сервиса, весьма специфична и этот вид различных логик в 100х местах.
Итак, есть ли способ прийти и по крайней мере применить пессимистический замок к этой ситуации?
Класс 'SomeCrazyClass' здесь может быть любым, а не только фасолью. уже имеют уровень сервиса для аннотации @Transactional. – Elbek
@elbek Если у вас есть автообновленная аннотация в SomeCrazyClass, она должна быть весенним бобом, не так ли? Так что, может быть, вы должны быть более точными с кодом, который вы публикуете. – forhas
Пожалуйста, прочитайте комментарий к классу, я написал его: «Этот класс может быть весенним бобом, возможно, не так. Если это не так, я получаю компонент SomeEntityService из общего appContext» – Elbek