Spring配置事务

Spring提供了两种事物管理的方法:声明式事务管理和编程式事务管理。

其中声明式事务管理是通过Spring AOP实现,能达到最少影响应用的代码,这是和非侵入性的轻量级容器的观念是一致的。大致总结一下声明事务的方法如下:

(1)使用AOP ProxyFactoryBean和TransactionIntercepter

       使用ProxyFactoryBean和TransactionIntercepter步骤

  1.定义数据源,事务管理类


    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
        destroy-method="close">
        <property name="driverClassName">
            <value>org.postgresql.Driver</value></property>
        <property name="url">
            <value>jdbc:postgresql://localhost/prospring</value></property>
        <property name="username"><value>janm</value></property>
        <property name="password"><value>****</value></property>
    </bean> 
    <bean id="transactionManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource"><ref local="dataSource"/></property>
    </bean>



  2.定义事务拦截器,such as:

 (2)使用TransactionProxyFactoryBean

  使用TransactionProxyFactoryBean:

1.事务管理类

<bean id="userManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target"><ref local="userManagerTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>


  TransactionProxyFactoryBean只是为组件的事务代理,如果我们要给组件添加一些业务方面的验证等,可以使用TransactionTemplate加拦截器方式,为组件添加多个拦截器,spring AOP中提供了三类Advice,即前增强,后增强,抛出异常时的增强,可以灵活使用。

    <bean id="transactionManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager"/>

2.定义事务代理

 

 (3)代码级元数据声明方法:

 (4)BeanNameAutoProxyCreator,另一种声明方式

TransactionProxyFactoryBean非常有用,当事 务代理包装对象时,它使你可以完全控制代理。如果你需要用一致的方式(例如,一个 样板文件,“使所有的方法事务化”)包装大量的bean,使用一个 BeanFactoryPostProcessor的一个实现, BeanNameAutoProxyCreator,可以提供另外一种方法, 这个方法在这种简单的情况下更加简单。

重述一下,一旦ApplicationContext读完它的初始化信息,它将初始化所有实 现BeanPostProcessor接口的bean,并且让它们后处理 ApplicationContext中所有其他的bean。所以使用这种机制,一个正 确配置的BeanNameAutoProxyCreator可以用来后处 理所有ApplicationContext中所有其他的bean(通过名称来识别),并且把它 们用事务代理包装起来。真正生成的事务代理和使用 TransactionProxyFactoryBean生成的基本一致,这里不再 讨论。

让我们看下面的配置示例:

 <!-- Transaction Interceptor set up to do PROPOGATION_REQUIRED on all methods -->
  <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>

  <!-- One BeanNameAutoProxyCreator handles all beans where we want all methods to use
       PROPOGATION_REQUIRED -->
  <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>


 假设我们在ApplicationContext中已经有一个TransactionManager的实例 ,我们首先要做的使创建一个 TransactionInterceptor实例。 根据通过属性传递的TransactionAttributeSource接口的一个实现, ransactionInterceptor决定哪个 方法被拦截。这个例子中,我们希望处理匹配 所有方法这种最简单的情况。这个不是最有效的方式,但设置非常迅速,因为 我可以使用预先定义的匹配所有方法的 MatchAlwaysTransactionAttributeSource类。如果我 们需要特定的方式,可以使用 MethodMapTransactionAttributeSourceNameMatchTransactionAttributeSourceAttributesTransactionAttributeSource

现在我们已经有了事务拦截器,我们只需把它交给我们定义的 BeanNameAutoProxyCreator实例中,这样AppliactonContext中 定义的6个bean以同样的方式被封装。你可以看到,这 比用TransactionProxyFactoryBean以一种方式单独封装6个bean简洁很 多。封装第7个bean只需添加一行配置。

你也许注意到可以应用多个拦截器。在这个例子中,我们还应用了一个 前面定义的HibernateInterceptor (bean id=hibInterceptor),它为我们管理 Hibernare的会话。

有一件事值得注意,就是在TransactionProxyFactoryBean, 和BeanNameAutoProxyCreator切换时bean的命名。 第一种情况,你只需给你想要包装的bean一个类似myServiceTarget的id, 给代理对象一个类似myService的id,然后所有代理对象的用户只需引用代理对象, 如myService(这些是通用命名规范, 要点是目标对象要有和代理对象不同的名称,并且它们都要在ApplicationContext中可用)。然而, 使用BeanNameAutoProxyCreator时, 你得命名目标对象为myService。 然后当BeanNameAutoProxyCreator后处理目标对象 并生成代理时,它使得代理以和原始对象的名称被插入到 ApplicationContext中。从这一点看,只有代理(含有被包装的对象)在ApplicationContext中可用。

<bean id = "transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributeSource">
<value>
com.test.UserManager.*r=PROPAGATION_REQUIRED
</value>
</property>
</bean>


  3.为组件声明一个代理类:ProxyFactoryBean

<bean id="userManager" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>com.test.UserManager</value></property>
<property name="interceptorNames">
<list>
<idref local="transactionInterceptor"/>
</list>
</property>
</bean>


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值