Spring 的声明式事务处理

Spring也提供了声明式事务管理。这是通过Spring AOP实现的。

Spring 中进行事务管理的通常方式是利用AOP(面向切片编程)的方式,为普通java类封装事务控制,它是通过动态代理实现的,
由于接口是延迟实例化的, spring在这段时间内通过拦截器,加载事务切片。

通常通过TransactionProxyFactoryBean设置Spring事务代理。我们需要一个目标对象包装在事务代理中。
这个目标对象一般是一个普通Java对象的bean。当我们定义TransactionProxyFactoryBean时,
必须提供一个相关的 PlatformTransactionManager的引用和事务属性。 事务属性含有上面描述的事务定义。

  <bean id="transactionManager"
     class="org.springframework.orm.hibernate3.HibernateTransactionManager">★★1
       <property name="sessionFactory">
       <ref local="sessionFactory" />
   </property>
  </bean>
 
  <bean id="userDAOProxy"
   class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">★★2
   <property name="transactionManager">★★3
     <ref bean="transactionManager" />
   </property>
   <property name="target">★★4
   <ref local="userDAO" />
   </property>
   <property name="transactionAttributes">★★5
     <props>
        <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
         <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
         <prop key="save">PROPAGATION_REQUIRED</prop>
         <prop key="write">PROPAGATION_REQUIRED,readOnly</prop>
     </props>
   </property>
  </bean>

  <bean name="/regedit" class="action.RegeditAction" scope="request">
      <property name="regedit">
   <ref bean="userDAOProxy"/>★★6
      </property>
  </bean>

  说明:★★1:是事务的消息类,属性值是sessionFactory,此类的实例会被作为参数传给★★3
            ★★2:TransactionProxyFactoryBean设置Spring事务代理
            ★★4:目标属性,是对具体的Bean进行事务处理,这里的id为"userDAOProxy"就是对"userDAO"的代理后的Bean引用。★★6就是对
               声明式事务后的"userDAO"Bean进行的注入。
            ★★5:这里的transactionAttributes属性定义在 org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource
               中的属性格式来设置。这个包括通配符的方法名称映射是很直观的。注意 get*的映射的值包括回滚规则。表示对get开头的方法进行事务处理。
               但指定的方法中只要产生异常,事务将会自动回滚。
               可以用逗号分隔定义多个回滚规则:
               PROPAGATION_REQUIRED表示当前方法必须运行在一个事务环境中。如果一个现有的事务在运行,该方法则运行在这个事务中,
               否则就要开始一个新的事务。
               PROPAGATION_MANDATORY表示当前方法必须运行在一个事务环境中,否则抛出异常。
               PROPAGATION_NEVER表示当前方法不能运行在一个事务环境中,否则抛出异常。
               PROPAGATION_REQUIRES_NEW表示当前方法必须运行在自己的事务里面。
               PROPAGATION_SUPPORTS表示当前方法不需要事务处理的环境,但这个方法在事务处理的环境中时,也不会报异常。
               一般来讲,我们将业务逻辑层的方法设置为 "PROPAGATION_REQUIRED" ,readOnly表示此方法中只能做查询,不能对数据的修改。
               然而,数据的查询是不需要事务的,所以,readOnly在这里没有实际的意义。

 

==========================================


下面提供一段完整的Spring的配置:


        //***************链接数据库的配置********************
       <bean id="database"
  class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName"
   value="com.microsoft.jdbc.sqlserver.SQLServerDriver">
  </property>
  <property name="url"
   value="jdbc:microsoft:sqlserver://localhost:1433">
  </property>
  <property name="username" value="sa"></property>
 </bean>


        //***************session工厂的配置********************
      <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
   <ref bean="database" />
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">
     org.hibernate.dialect.SQLServerDialect
    </prop>
   </props>
  </property>
  <property name="mappingResources">
   <list>
    <value>po/Users.hbm.xml</value></list>
  </property>
  </bean>


        //***************对Action进行配置(注意这里对"regedit"的注入,用的是声明式后的逻辑层的Bean)
  <bean name="/regedit" class="action.RegeditAction" scope="request">
       <property name="regedit">
             <ref bean="userserviceproxy"/>
       </property>
  </bean>

 

        //***************业务逻辑Bean的配置(要进行事务)********************
  <bean id="regedit" class="service.RegeditImpl" >
       <property name="dao">
              <ref bean="regeditdao"/>
       </property>
  </bean>

 

        //***************Dao的配置********************  
  <bean id="regeditdao" class="dao.UserDAOImpl">
    <property name="sessionFactory">
                     <ref local="sessionFactory" />
                  </property>
                </bean>


 
 
        //***************声明式事务处理的配置******************** 
  
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory">
               <ref local="sessionFactory" />
            </property>
        </bean>

<bean id="userserviceproxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
   <property name="transactionManager">
         <ref bean="transactionManager" />
   </property>
   <property name="target">
         <ref local="regedit" />   //***************对应要进行声明式事务处理的Bean******************** 
   </property>
   <property name="transactionAttributes">
   <props>
        <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
         <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
         <prop key="regedit">PROPAGATION_REQUIRED</prop>
         <prop key="write">PROPAGATION_SUPPORTS,readOnly</prop>
   </props>
   </property>
</bean>


========================================================================================


声明式事务处理的另一种配置方法


<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory">
               <ref local="sessionFactory" />
            </property>
</bean>

<bean id="userserviceproxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  abstract="true">★★1
   <property name="transactionManager">
         <ref bean="transactionManager" />
   </property>
   <property name="transactionAttributes">
   <props>
        <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
         <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
         <prop key="regedit">PROPAGATION_REQUIRED</prop>
         <prop key="write">PROPAGATION_SUPPORTS,readOnly</prop>
   </props>
   </property>
</bean>

 

<bean  id="fwxxbiz"  parent="userserviceproxy">★★2
   <property name="target"  ref="regedit">
</bean>

<bean  id="fwxxbiz2"  parent="userserviceproxy">
   <property name="target"  ref="regedit2">
</bean>

... ... ...


说明:
    这段配置与上面的这段配置基本上是相同的,唯一的区别是在配置TransactionProxyFactoryBean是没有指定具体的target属性,也就是
    没有指定具体的Bean要进行事务处理,而是定义了abstract属性,看★★1,有这种配置的表明,此Bean不能产生实例对象。
    而在★★2时,指定了父类Bean,并且填充了target属性。这样的配置的好处是,可以更灵活的指定对哪些Bean进行事务处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值