【问题标题】:Difference between HibernateTransactionManager and OpenSessionInViewFilterHibernateTransactionManager 和 OpenSessionInViewFilter 的区别
【发布时间】:2014-08-20 18:07:56
【问题描述】:

来自文档 - http://docs.spring.io/spring-framework/docs/2.0.x/api/org/springframework/orm/hibernate/HibernateTransactionManager.html

HibernateTransactionManager - 将 Hibernate Session 从指定工厂绑定到线程,可能允许每个工厂有一个线程绑定 Session

OpenSessionInViewFilter - 此过滤器使 Hibernate Sessions 通过当前线程可用,事务管理器将自动检测到。

两者有什么区别,应该在什么场景下使用?

【问题讨论】:

    标签: java spring hibernate spring-mvc transactions


    【解决方案1】:
    OpenSessionInViewFilter
    

    现在,当您使用OpenSessionInViewFilter 时,默认情况下会话的刷新模式设置为从不。因此,当您尝试使用 hibenate 在您的操作中保存某些内容并提交它时,它不会反映在您的数据库中。要解决此问题,您需要刷新操作类中的会话或扩展 OpenSessionInViewFilter 并覆盖 closeSession(Session session, SessionFactory sessionFactory)

    现在您也可以为每个请求维护一个事务。在您的操作中,您编辑对象的属性并使用session.update(object) 更新它。但它还没有提交,因为还有一些其他的处理。同时,其他一些请求正在调用一个尝试检索您正在更新的对象的操作。由于对象尚未提交,其他请求将获得旧对象。要解决此问题,您需要在加载对象之前开始事务并在更新对象后提交事务。这样只要对象是saved/updated,它就会被提交。有了这个,单个用户请求中可以有很多事务,但只有一个会话。

    OpenSessionInView 模式仅保证会话在单个线程执行期间是打开的。 当页面被渲染并返回到浏览器时,会话被过滤器关闭。

    因此后续请求(例如导航请求)需要另一个新会话,该会话将由 OpenSessionInViewFilter 打开。但是由于“旧”人对象没有连接到“新”会话,它被认为是断开的对象,其引用不能延迟加载。

    【讨论】:

    • 其实你错了。刷新模式设置为manual 不是从不。如果您使用 Spring 的事务支持,HibernateTransactionManager 将再次将其设置为AUTO(在提交后重置它)。所以会出现潮红。如果不是,则说明您的应用程序配置/设置有误。
    • @M.Deinum from class 注意:默认情况下,此过滤器不会刷新 Hibernate 会话,刷新模式设置为 FlushMode.NEVER。它假设与关心刷新的服务层事务结合使用:活动事务管理器将在读写事务期间临时将刷新模式更改为 FlushMode.AUTO,最后刷新模式重置为 FlushMode.NEVER每笔交易。如果您打算在没有事务的情况下使用此过滤器,请考虑更改默认刷新模式(通过“flushMode”属性)。
    猜你喜欢
    • 2016-07-01
    • 2012-12-28
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    相关资源
    最近更新 更多