`

spring事务

阅读更多

http://wiki.springside.org.cn/display/calvin/Spring+Notes spring Annotation

 

若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥有写权限。也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有transaction,并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.NEVER。所以受transaction保护的方法有写权限,没受保护的则没有。

  1. 可能的解決方式有:
    1、将singleSession设为false,这样只要改web.xml,缺点是Hibernate Session的Instance可能会大增,使用的JDBC Connection量也会大增,如果Connection Pool的maxPoolSize设得太小,很容易就出问题。
    2、在控制器中自行管理Session的FlushMode,麻烦的是每个有Modify的Method都要多几行程式。
          session.setFlushMode(FlushMode.AUTO);
          session.update(user);
          session.flush();
    3、Extend OpenSessionInViewFilter,Override protected Session getSession(SessionFactory sessionFactory),将FlushMode直接改为Auto。
    4、让方法受Spring的事务控制。这就是常使用的方法:

采用spring的事务声明,使方法受transaction控制


  1.   <bean id="baseTransaction"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
              abstract="true">
            <property name="transactionManager" ref="transactionManager"/>
            <property name="proxyTargetClass" value="true"/>
            <property name="transactionAttributes">
                <props>
                    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                    <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="add*">PROPAGATION_REQUIRED</prop>
                    <prop key="update*">PROPAGATION_REQUIRED</prop>
                    <prop key="remove*">PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>

  2.     <bean id="userService" parent="baseTransaction">
            <property name="target">
                <bean class="com.phopesoft.security.service.impl.UserServiceImpl"/>
            </property>
        </bean>
 

对于上例,则以save,add,update,remove开头的方法拥有可写的事务,如果当前有某个方法,如命名为importExcel(),则因没有transaction而没有写权限,这时若方法内有insert,update,delete操作的话,则需要手动设置flush model为Flush.AUTO,如


  1. session.setFlushMode(FlushMode.AUTO);
  2. session.save(user);
  3. session.flush();

key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)。
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。这是一个最优化提示。在一些情况下,一些事务策略能够起到显著的最优化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)时避免dirty checking(试图“刷新”)。
在事务属性中还有定义“timeout”值的选项,指定事务超时为几秒。在JTA中,这将被简单地传递到J2EE服务器的事务协调程序,并据此得到相应的解释。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics