开发者

What happens if you don't roll back a transaction in Hibernate?

Everything I read about Hibernate states that you must roll back a transaction and close the session when an error occurs, and there's usually some variation of the following code (taken from Hibernate's docs) given as an example:

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();
}

This pattern seems odd to me for a couple of reasons. First, it jus开发者_如何学JAVAt seems unreasonably complicated for a framework that's generally geared towards making things simple. More importantly, what happens if the code in the try block throws something other than a RuntimeException? It looks as if Hibernate must be able to gracefully close the session with an open transaction in that case, presumably by rolling it back, but if that's true, why bother calling rollback at all?


Hibernate may make a lot of things simpler, but transaction management just isn't very simple so for every transaction you have to think very carefully what you want. Hibernate can't help you with that.

If the code in the try block throws anything other than a RuntimeException, your transaction obviously does not commit. But you do not explicitly rollback either. The sess.Close call in your finally block doesn't rollback the transaction either. What happens depends on whether this is a nested transaction:

  • If it is not, then eventually the transaction times out and rolls back.
  • If it is, the parent transaction will see that a child transaction has not committed when it commits itself. This will result in a rollback of the entire transaction.


More importantly, what happens if the code in the try block throws something other than a RuntimeException?

If any other exception is possible in the block of code in the try block apart from RuntimeException, that will have to be a checked exception, which will be caught by the compiler itself, and you would end up in incorporating the handling part of it in your code.

In the example provided in this question, we are catching only RuntimeException which is I feel is the right way to code. By doing this, we can rollback the transaction straight away without having to wait for a transaction time out and eventual rollback. As we continue to re-throw the RuntimeException, we are not breaking the exception flow as well. This is cleaner and more explicit way of working with the transaction than letting the transaction timeout to trigger the rolling back of the transaction.

Of course, we should NOT catch 'Exception' in the way RuntimeException is being caught for obvious reasons.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜