Что произойдет, если вы не откатите транзакцию в Hibernate? - PullRequest
7 голосов
/ 28 августа 2010

Все, что я читал о Hibernate, гласит, что вы должны откатить транзакцию и закрыть сеанс при возникновении ошибки, и обычно есть несколько вариантов следующего кода (взятого из документов Hibernate), приведенного в качестве примера:

Session sess = factory.openSession();
Transaction tx = null;
try {
    tx = sess.beginTransaction();
    // do some work
    ...
    tx.commit();
} catch (RuntimeException e) {
    if (tx != null) tx.rollback();
    throw e; // or display error message
} finally {
    sess.close();
}

Эта модель кажется мне странной по нескольким причинам.Во-первых, это просто кажется неоправданно сложным для структуры, которая обычно ориентирована на упрощение.Что еще более важно, что произойдет, если код в блоке try выдаст что-то отличное от RuntimeException?Похоже, что Hibernate должен быть в состоянии изящно закрыть сеанс с открытой транзакцией в этом случае, предположительно, откатив его назад, но если это правда, зачем вообще вызывать rollback?

Ответы [ 2 ]

4 голосов
/ 28 августа 2010

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

Если код в блоке try выдает что-то отличное от RuntimeException, ваша транзакция, очевидно, не фиксируется. Но вы также явно не откатываетесь. Вызов sess.Close в вашем finally блоке также не отменяет транзакцию. Что происходит, зависит от того, является ли это вложенной транзакцией:

  • Если это не так, то в конечном итоге транзакция останавливается и откатывается.
  • Если это так, родительская транзакция увидит, что дочерняя транзакция не зафиксирована, когда она фиксирует себя. Это приведет к откату всей транзакции.
0 голосов
/ 08 ноября 2014

Что еще более важно, что произойдет, если код в блоке try сгенерирует что-то кроме RuntimeException?

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

В примере, приведенном в этом вопросе, мы ловим только RuntimeException, которое, я считаю, является правильным способом кодирования. Сделав это, мы можем сразу же откатить транзакцию, не дожидаясь истечения времени ожидания транзакции и возможного отката. Продолжая перезапускать RuntimeException, мы также не нарушаем поток исключений. Это более чистый и более явный способ работы с транзакцией, чем предоставление тайм-аута транзакции для запуска отката транзакции.

Конечно, мы НЕ должны перехватывать 'Exception' так, как по очевидным причинам перехватывается RuntimeException.

...