视图中的Hibernate Open会话:每个请求的事务?

Mar*_*rvo 11 spring hibernate sessionfactory open-session-in-view

我在Tomcat上使用Hibernate和Spring.我一直在阅读并重新阅读关于该主题的指向JBoss wiki页面的内容,这很有帮助.但它给我留下了一些问题.

  1. 为每个请求启动交易的想法让我很烦恼.我想我可以将过滤器限制在某些控制器 - 可能将我需要交易的所有控制器放在伪"tx"路径下.但如果您不知道是否需要交易,那么使用交易不是一个坏主意吗?如果我只是在某些请求中读取 - 很可能来自缓存的读取 - 在没有事务的情况下我不是更好吗?

  2. 我读过帖子,提到他们如何处理服务层的事务,我想用Spring做这件事.但那么过滤器代码是什么样的呢?我仍然希望在我的视图中可以使用会话进行一些延迟加载.

  3. 如果我所要做的就是调用sessionFactory.getCurrentSession()我的过滤器,它如何被"释放"回会话工厂重新使用?(session.close()即使在使用事务时,我也希望看到一个或者什么.)谁在告诉会话工厂该会话可以重用?

  4. 也许beginTransaction()是在请求期间将给定数据库连接绑定到给定会话的调用?否则,会话根据需要从池中提取数据库连接,对吧?

感谢您对我的所有问题的耐心等待.

(如果你的答案将成为Spring文档的链接,那么你只会让我哭泣.你不想要那个,是吗?如果人们不再回答Spring相关的问题,我会付真钱吗办法.)

gka*_*mal 20

您的疑虑是有效的,维基页面上提供的解决方案过于简单.不应在Web层管理事务 - 应在服务层处理.

正确的实现将打开一个会话并将其绑定到过滤器中的一个线程.没有开始交易.会话处于刷新模式从不 - 只读模式.服务调用会将会话设置为刷新模式auto&start/commit the transaction.一旦服务方法完成,会话刷新模式将恢复为从不.

还有一个选项可以不在过滤器中打开会话.每个服务层调用将打开一个单独的会话和事务 - 在服务调用完成后,会话未关闭,但注册为延迟关闭.Web请求处理完成后,会话将关闭.

Spring提供了OpensessionInViewFilter,它的工作原理如上所述.所以忽略jboss wiki文章,只需配置OpensessionInViewFilter - 一切都会好的.

SessionFactory.getCurrentSession() - 在内部创建会话并将其分配给本地线程.每个请求/线程都有自己的会话.Web请求处理完成后,会话将关闭.在代码中,您只需要使用SessionFactory.getCurrentSession(),而不必关闭它.jboss wiki页面上的代码示例是错误的 - 它应该在finally块中有一个SessionFactory.getCurrentSession().close().或者他们可能正在使用JTA事务并将hibernate配置为与JTA事务一起打开/关闭会话.