当前位于具有本地和远程EJB的MDB(Singleton和Stateless)的JavaEE应用程序服务器中,我正在使用JDBC-Transactions for Hibernate Core。在抛出异常时回滚事务并关闭连接
管理自己我所有的开启和关闭,提交休眠会话和事务可能导致连接泄漏和未合并的事务。
特别是在编程错误导致自定义或未经检查的异常未捕获并抛出到远程客户端的情况下。
什么是最简单或最好的方式来确保我的休眠会话被关闭,事务回滚以防错误发生?
使用容器管理的事务(CMT)还是可以关闭在任何EJB方法返回时调用的拦截器内的会话?
一个简单的方法是将会话范围的用法包装在try-catch块中,并捕获任何类型的异常,但采用较少代码的一般方法会受到青睐。
编辑:远程EJB实例
我低级别的Hibernate DAO不关闭连接和抛出的异常回滚事务。问题是业务逻辑之间的DAO访问的情况下,连接仍处于打开*
public void doSomething(Foo foo) throws Exception { // open session and transaction Session session = DAO.openSession(); // retrieve data Bar bar = DAO.get(session, ...) // call other methods which throws an exception resulting in open connection doOtherStuff(foo, bar) DAO.save(session, foo); // commit transaction DAO.closeAndCommitSession(session); }
现在我使用的是大的try-catch-最后:
public void doSomething(Foo foo) throws Exception
{
// open session and transaction
Session session = DAO.openSession();
try
{
// retrieve data
Bar bar = DAO.get(session, ...)
// call other methods which throws an exception resulting in open connection
doOtherStuff(foo, bar)
DAO.save(session, foo);
}
catch (final Exception e)
{
DAO.rollBackTransaction(session);
throw e;
}
finally
{
DAO.closeAndCommitSession(session);
}
}
这将需要每个方法的'ConnectionRunnable',这似乎是非常大的开销。关闭连接是最低优先级,因为这只是一个编程错误。问题更多的是未捕获的异常,当连接仍处于打开状态并且事务未回滚时,将抛出异常。 – djmj
@djmj:Beryllium提出的解决方案看起来简洁而优雅,即使它需要每个连接的匿名内部类。这里的美妙之处在于,它允许您以更确定的方式管理资源并处理异常。我错过了什么吗? – scottb
@scottb不错的总结!我只想补充说,在使用站点上需要更少的代码行:嵌套的异常处理在每个使用站点都会使代码混乱。 – Beryllium