Я хочу описать проблему, используя следующий пример:
Предположим, что мы разрабатываем приложение (на основе Hibernate JPA и Spring), которое позволяет его пользователям выполнять два вида транзакционных операций, которые должны выполняться в сериализуемом режиме для каждого пользователя. Поскольку приложение должно быть надежным и эффективно работать в одно и то же время, мы можем использовать какую-то оболочку для ReentrantLock для синхронизации:
void operation1(user) {
userLockWrapper.lock(user.id); //gets ReentrantLock for specified id from internal map and locks it
try {
//start transaction
//perform operation
//commit transaction
} finally {
userLockWrapper.unlock(user.id).
}
}
void operation2(user) {
userLockWrapper.lock(user.id); //same wrapper instance as in operation1
//same logic as in operation1
}
Теперь давайте предположим, что для повышения масштабируемости мы разделили нашу систему на два автономных модуля, которые работают на разных виртуальных машинах и используют одну и ту же базу данных, где первый отвечает за операцию1, а второй - за работу2. Первое решение, которое приходит на ум, - это использование пессимистичных блокировок, например ::1006
@Transactional
void operation1(user) { //same goes for operation2
//firing extra select for update sql statement here
entityManager.find(User.class, user.id, LockModeType.PESSIMISTIC_WRITE)
//performing operation
}
Мне интересно, есть ли более предпочтительные решения для этого. Надеюсь получить несколько советов от сообщества.