Блокировка выполнения взаимных транзакций - PullRequest
0 голосов
/ 04 января 2012

Я хочу описать проблему, используя следующий пример:

Предположим, что мы разрабатываем приложение (на основе 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      
}

Мне интересно, есть ли более предпочтительные решения для этого. Надеюсь получить несколько советов от сообщества.

1 Ответ

2 голосов
/ 04 января 2012

Да, есть. Используйте оптимистическую блокировку. Вам просто нужно добавить постоянное поле с аннотацией @Version к вашим сущностям и понять, как оно работает. Читать http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#transactions-optimistic

Каждый раз, когда Hibernate записывает объект в базу данных, он проверяет, что сохраненная версия остается такой же, как и в памяти, и увеличивает эту версию. Если версии не совпадают, генерируется откат транзакции.

Это то, что обеспечивает наилучшую пропускную способность, и это также единственная система, которая может использоваться для двух транзакций: первая транзакция загружает объект, пользователь изменяет его (что может занять несколько минут), вторая транзакция объединяет объект. 1006 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...