пессимистическая блокировка с подготовленным спящим режимом

У меня есть система пакетной обработки, которая объединяет счетчики успехов. Многие серверы выполняют агрегацию, одновременно обновляя одну строку в таблице. Я выполняю подготовленные операторы, используя hibernate, как это

SQL_UPDATE = "UPDATE STATS.COUNTS SET SUCCESSCOUNT = SUCCESSCOUNT + ? WHERE ID = ?"
update = session.connection().prepareStatement(SQL_UPDATE);
update.setLong(1, data.getSuccessCount());
update.setLong(2, data.getBatchId());
update.execute();

Было несколько проблем с параллелизмом, и было решено использовать пессимистическую блокировку, поскольку вероятность коллизии довольно высока. Как выполнить пессимистическую блокировку при использовании таких подготовленных операторов в спящем режиме.


person zolo    schedule 02.01.2014    source источник
comment
Вы делаете это через собственный SQL, а не через Hibernate, поэтому он не может вам помочь. Если вы выполняете запрос в транзакции, сначала выполните SELECT...FOR UPDATE, который заблокирует, как вы хотите.   -  person Boris the Spider    schedule 02.01.2014
comment
@BoristheSpider, описанное выше, выполняется в самой транзакции. Под выбором... для обновления вы подразумеваете сначала получение объекта, а затем обновление? Если я выполню выбор... для обновления, разве это не два запроса, попадающие в базу данных (1 для выбора и 1 для обновления) вместо 1 в этом случае?   -  person zolo    schedule 02.01.2014


Ответы (2)


Если вас беспокоит параллелизм, вы можете изменить уровень изоляции транзакций со значения по умолчанию на SERIALIZABLE. Это высший уровень изоляции. Самая высокая изоляция может увеличить вероятность взаимоблокировки и, следовательно, проблем с производительностью.

Опять же, если это пакетное обновление, лучше не иметь высокого уровня изоляции. Вы можете рассмотреть возможность оценки пакетных технологий, таких как Spring Batch.

person shatk    schedule 03.01.2014

Вы не упомянули об установке уровня изоляции ваших транзакций. Вы пытались установить его, используя что-то вроде @Transactional(isolation=Isolation.SERIALIZABLE, propagation=Propagation.REQUIRED)

В противном случае методы блокировки сеанса Hibernate работают с объектами и не применяются к SQL DDL.

person Not a code monkey    schedule 02.01.2014