Hibernate Stateless Session лучший способ обработки ошибок?
Я работаю с сеансом без сохранения состояния для пакетной работы в моем проекте Play Framework 1.2.4.
Я вставляю и обновляю строки довольно хорошо, но я не знаю, что делать, когда произошло исключение. Вот мой код:
try{
statelesssession.insert(someobject);
}
catch(ConstraintViolationException e) //It happens from time to time dont ask me why..
{
??????transaction.rollback();????? THATS MY CONCERN
}
finally{
transaction.commit();
}
Что мне нужно знать, так это то, что я фиксирую данные на каждые 100 вставок. мне интересно, если ограничение нарушается, то есть 56-я запись и транзакция выполняет откат, я тоже потеряю другие 55 записей?
если да, что я должен делать в исключении ограничений? или я должен зафиксировать в каждой 1 записи, чтобы избежать этого?
3 ответа
Если вы фиксируете каждые 100 вставок, то откат после 56-й вставки также отменяет все 55 вставок до.
Вы можете фиксировать после каждой вставки, но в пакетах, которые вставляют действительно много строк, что является медленным и поэтому не рекомендуется.
Решение использует точки сохранения.
Установка точки сохранения выполняется относительно быстро. Это можно сделать после каждой вставки. Установка точки сохранения не записывает никаких данных в базу данных - вам все еще придется зафиксировать позже - но откат выполняется только до последней точки сохранения.
Таким образом, в вашем примере вы фиксируете каждые 100 (или любые другие) строки (и после последней строки наверняка), и вы устанавливаете точку сохранения после каждой строки. Когда появляется ошибка и вы откатываете действие, отменяется только вставка с ошибкой, остальные не затрагиваются.
Описание см., Например, java.sql.Connection.setSavepoint, java.sql.Savepoint или здесь.
В случае отката вы также потеряете все предыдущие записи в транзакции. Если вы хотите потерять только записи с исключениями из ограничений, то вы можете хранить записи каждой партии в списке и переключаться на фиксацию по одной, когда пакетные бомбардировки продолжаются, и продолжайте делать партии позже.
В этом случае использования у вас есть другое задание, которое разбивает все ваши данные на 100 объектов и запускает вспомогательную работу для этих объектов.
Лучшее, что можно сделать в этом случае для меня, это бросить исключение. Затем основная работа получит это исключение, и все ваши 100 объектов отката. Затем мастер-задание может перейти в другой режим для этих объектов и перезапустить подзадачу для каждого объекта. Тогда только тот, который выбрасывает исключение, не будет сохранен.
Это типичная обработка партии. Если все в порядке, ваш пакет работает быстро, потому что вы фиксируете каждые 100 объектов, но в случае ошибки вы возвращаетесь к фиксации одного объекта, поэтому вы просто не сохраняете объекты, которые потерпели неудачу.
Но, как сказал mericano1, правильное поведение в вашем случае зависит от бизнес-правил.