我读到的关于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
呢?
答案 0 :(得分:4)
Hibernate可能会使很多事情变得更简单,但事务管理并不是很简单,因此对于每个事务,您必须非常仔细地考虑您想要的事情。 Hibernate无法帮助你。
如果try
块中的代码抛出除RuntimeException
以外的任何内容,则您的事务显然不会提交。但是你也没有显式回滚。 sess.Close
阻止中的finally
调用也不会回滚事务。会发生什么取决于这是否是嵌套事务:
答案 1 :(得分:0)
更重要的是,如果try块中的代码抛出会发生什么 除了RuntimeException以外的东西?
如果除了RuntimeException之外,try块中的代码块中可能存在任何其他异常,则必须是一个已检查的异常,它将被编译器本身捕获,并且最终会合并处理部分在你的代码中。
在这个问题中提供的示例中,我们只捕获RuntimeException,我觉得这是正确的代码方式。通过这样做,我们可以直接回滚事务,而无需等待事务超时和最终回滚。当我们继续重新抛出RuntimeException时,我们也没有打破异常流。这比使事务超时触发事务回滚更清晰,更明确地处理事务。
当然,我们不应该抓住'例外'因为显而易见的原因,正在捕获RuntimeException。