2015-05-29 7 views
3

EnvironmentHibernate сохраняет устаревшие данные с hibernate.jdbc.batch_versioned_data

Hibernate 4,2

ojdbc6 - Oracle 11.2.0.3.0 JDBC 4.0

Oracle Database 11g

Этот вопрос

Мы следовали за многими рекомендациями ations настроить наш спящий режим дозирования следующим образом:

<property name="hibernate.jdbc.batch_size">100</property> 
<property name="hibernate.order_inserts">true</property> 
<property name="hibernate.order_updates">true</property> 
<property name="hibernate.jdbc.batch_versioned_data">true</property> 

Мы проверили наши журналы, и мы увидели, что сгенерированные операторы SQL дозируют. Однако, если две транзакции одновременно изменяют одни и те же строки с версией сущностей, Hibernate успешно выполнит оба из них, что приведет к потере противоречивых обновлений в транзакции, совершившей последние (в обеих транзакциях сохраняются несогласные данные, поэтому последняя транзакция выходит из базы данных в несогласованном состоянии).

Удивительно, но документации по этому поведению очень мало. Hibernate официальный documentation говорит:

hibernate.jdbc.batch_versioned_data

Установите это свойство истинно, если ваш возвращает драйвер JDBC правильный подсчет строк из executeBatch(). обычно безопасен, чтобы включить эту опцию. Затем Hibernate будет использовать пакетный файл DML для автоматических версий данных. По умолчанию false.

Обычно безопасный? Мы почти отправили это на производство, прежде чем заметить, что все версии были нарушены.

Мы вышли из игры blog пять лет назад, которая описывает эту странность; очевидно, что Hibernate долгое время не делал этого.

Есть ли причина, по которой Hibernate ведет себя так? Он получает информацию от драйвера jdbc о том, что количество обновленных строк неизвестно, почему оно не выдает исключение, чтобы указать его, но скорее оставляет впечатление, что проверка версии прошла успешно?

+0

у вас устали делая это ' истинный' ложь? – Babel

ответ

4

Драйвер oracle должен возвращать правильные подсчеты строк. Я буду удивлен, если это не так. Могли ли вы подтвердить правильность результатов работы драйвера? Вы можете включить ведение журнала Hibernate, чтобы проверить это.

Пара вещей, чтобы проверить:

  1. Вход фактический SQL отправляется в базу данных и проверить, что столбец версия упоминается в пункте где. Не уверен, что SQL-запросы регистрируются журналом Hibernate с пакетной загрузкой, вам может потребоваться другой способ регистрации SQL-ов тогда (например, p6spy)

  2. Если количество строк корректно возвращается во время параллельных обновлений, то приложение работает нормально. Подтвердите это, проверив, что значения столбца версии исправлены.

Update По следующей ссылке, этот вопрос присутствует с драйвером Oracle до 11g и фиксируется в версии 12с

https://hibernate.atlassian.net/browse/HHH-3360

Для предыдущих версий Oracle есть некоторые дополнительные информация, которая должна быть полезной, т. е. предоставляется индивидуальное решение.

Дополнительные ресурсы: https://hibernate.atlassian.net/browse/HHH-5070

+0

Драйвер oracle возвращает -2 (неизвестно); Я отлаживал это: 'org.hibernate.jdbc.Expectations.BasicExpectation.checkBatched'. –

+0

Это зарегистрировано Hibernate как _Supccess пакетного обновления unknown_ на уровне отладки (еще одна удивительная вещь, это должно быть, по крайней мере, предупреждение, но, на мой взгляд, самым интуитивным поведением было бы исключение здесь). 1) Фактический SQL содержит столбец версии в предложении where. 2) Столбец версии увеличивается на один после завершения обеих транзакций (значение, записанное первой транзакцией). –

+0

Пожалуйста, уточните мой обновленный ответ – codedabbler