我在Tomcat上使用Spring的Hibernate。我一直在阅读和重新阅读该主题上指向JBoss Wiki页面的信息,这很有帮助。但这使我有些疑问。
为每个请求启动事务的想法困扰着我。我想我可以将过滤器限制为某些控制器-也许将需要事务的所有控制器放在伪“ tx”路径下。但是,如果您不知道是否需要交易,使用交易不是一个坏主意吗?而且,如果我只是在某些请求中进行读取(读取很有可能来自缓存),那么没有交易我会更好吗?
我读过一些帖子,提到它们如何在服务层处理事务,我想在Spring中做到这一点。但是,过滤器代码是什么样的?我仍然希望该会话在我的视图中可用以进行一些延迟加载。
如果我要做的就是sessionFactory.getCurrentSession()在过滤器中调用,它如何“释放”回会话工厂以供重用?(session.close()即使使用事务,我也希望看到一个或一个东西。)谁在告诉会话工厂该会话可以重用?
sessionFactory.getCurrentSession()
session.close()
也许beginTransaction()是在请求期间将给定数据库连接绑定到给定会话的调用?否则,会话会根据需要从池中拉数据库连接,对吗?
beginTransaction()
感谢您耐心等待我所有的问题。
(如果您的答案将链接到Spring文档,您只会让我哭泣。您不想要那样吗,如果人们停止回答与Spring相关的问题,我将付钱给我。道路。)
您的担忧是正确的,Wiki页面上提供的解决方案过于简单。交易不应在Web层进行管理-交易应在服务层进行。
正确的实现将打开一个会话并将其绑定到过滤器中的线程。没有事务开始。会话进入刷新模式永不- 只读模式。服务调用会将会话设置为自动刷新模式并启动/提交事务。服务方法完成后,会话刷新模式将恢复为从不。
还有一个选项可以不打开过滤器中的会话。每个服务层调用都会打开一个单独的会话和事务- 在完成服务调用后,会话不会关闭,但会注册为延迟关闭。Web请求处理完成后,会话将关闭。
Spring提供了如上所述的OpensessionInViewFilter。因此,请忽略jboss Wiki文章,仅配置OpensessionInViewFilter-一切都会好起来。
SessionFactory.getCurrentSession()-在内部创建会话并将其分配给本地线程。每个请求/线程都会有自己的会话。Web请求处理完成后,会话将关闭。从代码中,您只需要使用SessionFactory.getCurrentSession()即可,而不必关闭它。jboss Wiki页面上的代码示例是错误的- 在finally块中应该有一个SessionFactory.getCurrentSession()。close()。或者他们可能正在使用JTA事务,并且将hibernate配置为与JTA事务一起打开/关闭会话。