spring 2.0 关于事务的变化(主要为声明性事务)

spring 2.0 关于事务的变化(主要为声明性事务)

在 1.x中,spring 的事务声明,一直是采用动态代理bean 实现的,也就是采用ProxyFactoryBean或者子类TransactionProxyFactoryBean来实现的

考虑下面的例子:(用1.x实现)
<bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory"/>
  </bean>

  <bean id="myProductService" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="proxyInterfaces" value="product.ProductService"/>
    <property name="target">
        <bean class="product.DefaultProductService">
            <property name="productDao" ref="myProductDao"/>
        </bean>
    </property>
    <property name="interceptorNames">
      <list>
        <value>myTxInterceptor</value> <!-- the transaction interceptor (configured elsewhere) -->
      </list>
    </property>
  </bean>

 <bean id="myTxInterceptor"

class="org.springframework.transaction.interceptor.TransactionInterceptor">

<property name="transactionManager">

   <ref bean="myTransactionManager"/>

</property>

<property name="transactionAttributeSource">

  <value>

   product.ProductService.increasePrice*=PROPAGATION_REQUIRED

  product.ProductService.someOtherBusinessMethod=PROPAGATION_MANDATORY

  </value>

</property>

</bean>

或者

<bean id="myProductService"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager">

<ref bean="myTransactionManager"/>

</property>

<property name="target">

<ref bean="myProductServiceTarget"/>

</property>

<property name="transactionAttributes">

<props>

<prop key="increasePrice*">PROPAGATION_REQUIRED</prop>

<prop key="someOtherBusinessMethod">PROPAGATION_MANDATORY</prop>

</props>

</property>
</bean>

当然,这需要每个服务接口都要声明一个事务bean ,这比较麻烦,当然,spring 也提供了另外一种解决方案

采用BeanNameAutoProxyCreator 自动代理声明入口来全局声明所有的事务。
<bean id="matchAllWithPropReq"
         class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource">
         <property name="transactionAttribute"><value>PROPAGATION_REQUIRED</value></property>
</bean>

<bean id="matchAllTxInterceptor"
         class="org.springframework.transaction.interceptor.TransactionInterceptor">
         <property name="transactionManager"><ref bean="transactionManager"/></property>
         <property name="transactionAttributeSource"><ref bean="matchAllWithPropReq"/></property>
</bean>
<bean id="autoProxyCreator"
         class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
         <property name="interceptorNames">
            <list>
               <idref local="matchAllTxInterceptor"/>
               <idref bean="hibInterceptor"/>
            </list>
         </property>
         <property name="beanNames">
            <list>
               <idref local="core-services-applicationControllerSevice"/>
               <idref local="core-services-deviceService"/>
               <idref local="core-services-authenticationService"/>
               <idref local="core-services-packagingMessageHandler"/>
               <idref local="core-services-sendEmail"/>
               <idref local="core-services-userService"/>
            </list>
         </property>
</bean>
list中包含了所有需要实现事务的服务bean 

 spring 2.0带来的aop变化和bean xml schema的变化,使得事务的处理变得更加的简单,
同aop一样,事务也采用两种方式来处理,一种主要为xml 声明,另外的一种也就是注释的引入。
先来看第一种情况:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

  <!-- SessionFactory, DataSource, etc. omitted -->

  <bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory"/>
  </bean>
 
  <aop:config>
   <!-- 这定义了主要的切面,也就是那些接口可以使用事务,这里只是说执行ProductService的所有方法-->
    <aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
  </aop:config>
  <!--主要的事务 advice 声明事务的相关属性-->
  <tx:advice id="txAdvice" transaction-manager="myTxManager">
    <tx:attributes>
      <tx:method name="increasePrice*" propagation="REQUIRED"/>
      <tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/>
      <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
  </tx:advice>

  <bean id="myProductService" class="product.SimpleProductService">
    <property name="productDao" ref="myProductDao"/>
  </bean>

</beans>

第二种方式,使用 @Transactional 注释

@Transactional

public interface FooService {

 

    Foo getFoo(String fooName);

 

    Foo getFoo(String fooName, String barName);

 

    void insertFoo(Foo foo);

 

    void updateFoo(Foo foo);

}


xml 配置

<!-- from the file 'context.xml' -->

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:aop="http://www.springframework.org/schema/aop"

       xmlns:tx="http://www.springframework.org/schema/tx"

       xsi:schemaLocation="

       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd

       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

 

  <!-- this is the service object that we want to make transactional -->

  <bean id="fooService" class="x.y.service.DefaultFooService"/>

 

  <!-- enable the configuration of transactional behavior based on annotations -->

  <tx:annotation-driven/>

 

  <!-- a PlatformTransactionManager is still required -->

  <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

    <!-- sourced from somewhere else -->

    <property name="dataSource" ref="dataSource"/>

  </bean>

 

  <!-- other <bean/> definitions here -->

 

</beans>

public class DefaultFooService implements FooService {

 

    public Foo getFoo(String fooName) {

        // do something

    }

 

    // these settings have precedence

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)

    public void updateFoo(Foo foo) {

        // do something

    }

}

你可能感兴趣的:(spring 2.0 关于事务的变化(主要为声明性事务))