`
java虫
  • 浏览: 532298 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

OpensessionInView学习

阅读更多
downpour 写的OpenSessionInView详解
http://www.iteye.com/topic/32001?page=1

SpringSide团队日志
http://calvin.blog.javascud.org/post/46.htm

HibernateTemplate中HibernateCallback的事务
http://www.blogjava.net/caixuetao/articles/113433.html

open session and Hibernate事务处理机制
http://blog.csdn.net/Explorering/archive/2006/06/14/797399.aspx

Hibernate事务
http://www.yesky.com/imagesnew/software/spring/orm.html

看完以上文章,对OpensessionInView有了更深的理解.

它为了实现Hibernate的延迟加载功能。基于一个请求一个hibernate session的原则。

spring中对OpenSessionInViewFilter的描述如下:
它是一个Servlet2.3过滤器,用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。
例如: 它允许在事务提交之后延迟加载显示所需要的对象。

一.如果配置OpensessionInView

1)request请求,服务器开个线程响应客户端
2)OpenSessionInViewFilter打开Session) ,绑定到当前线程
3) ServletDispatcher -> Action
4)打开Connection,启动事务) -> spring bean -> another spring bean -> (提交事务) -> bean执行完毕,
5)返回Action
6)render view(JSP/Template)
7)(OpenSessionInViewFilter关闭Session和Connection,取消绑定

其中第四步,在bean的dao里调用某方法时,继承的HibernateDaoSupport类,它的的HibernateTemplete的session也是判断当前线程有无session,若有的话直接使用.

对于Spring的OpenSessionInViewFilter来说,虽然数据库连接被保持了过长的时间,但是并没有锁定数据库资源,特别是事务资源。因为Spring的事务是通过TransactionInterceptor来实现的,在MVC结构中,当最后一个业务bean被调用结束以后,Transaction就已经被提交了。此后,虽然数据库连接还保持中,但是数据库资源没有锁定问题。



二.如果没用OpensessionInView

如果没有配置OpensessionInView,HibernateTemplete里的方法每次都是新开一个session,执行完关闭session

假设在你的应用中Hibernate是通过spring 来管理它的session.而且在你的应用中没有使用OpenSessionInViewFilter或者OpenSessionInViewInterceptor。session会在transaction结束后关闭。
如果你采用了spring的声明式事务模式,它会对你的被代理对象的每一个方法进行事务包装(AOP的方式)。如下:
 <bean id="txProxyTemplate" abstract="true"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
            <props>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="remove*">PROPAGATION_REQUIRED</prop>
                <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>
        </property>
    </bean>

    <bean id="manager" parent="txProxyTemplate">
        <property name="target">
            <bean class="org.appfuse.service.impl.BaseManager">
                <property name="dao" ref="dao"/>
            </bean>
        </property>
    </bean>

spring默认对RunTimeException及其子类回滚(例如DAOAccessException),也可以通过配置对任何CheckedException回滚

目标类org.appfuse.service.impl.BaseManager 的  save *方法的事务类型PROPAGATION_REQUIRED  ,remove* 方法的事务类型PROPAGATION_REQUIRED,其他的方法的事务类型是PROPAGATION_REQUIRED,readOnly。
所以调用这个名为“manager”的bean的方法之后session就关掉了.

关于事务:
在业务层用AOP的方式通过TransactionInterceptor进行了事务的begin和commit的拦截,而在两个方法之间,你的transactionStatus一直与Thread绑定,在事务声明为required的时候DAO的方法都会参与到这个事务中,就是说这是同一个事务
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics