Spring事务管理---声明式(1)利用

 

TransactionProxyFactoryBean生成事务管理

 

通常建议采用声明式事务管理

优势:代码中无需关注事务逻辑,让spring声明式事务管理负责事务逻辑,声明式事务管理无需与具体的事务逻辑耦合,可以方便地在不同事务逻辑之间切换。

 

声明式事务管理的配置方式,通常有如下三种:

1、  使用TransactionProxyFactoryBean为目标bean生成事务代理的配置。此方式是最传统,配置文件最臃肿、难以阅读的方式

2、  采用bean继承的事务代理配置方式,比较简洁,但依然是增量式配置

3、  使用beanNameAutoProxyCreator,根据bean name自动生成事务代理的方式,这个是直接利用spring的aop框架配置事务代理的方式,需要对spring的aop框架有所理解,但是这种方式避免了增量式配置,效果非常不错

4、  DefaultAdvisorAutoProxyCreator:这个也是直接利用spring的aop框架配置事务代理的方式,效果也非常不错,只是这种方式的可读性不如第三种方式

 

1、利用TransactionProxyFactoryBean生成事务代理

 

采用这种配置的时候,配置文件增长的非常快,每个bean有需要两个bean配置,一个目标,另外还需要使用TransactionProxyFactoryBean配置一个代理bean。这是一种最原始的配置方式,下面是使用TransactionProxyFactoryBean的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
 
    <!-- JDBC Properties -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
              <value>classpath*:jdbc.properties</value>
           </list>
       </property>
    </bean>
 
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
       <property name="driverClassName" value="${jdbc.driverClassName}" />
       <property name="url" value="${jdbc.url}" />
       <property name="username" value="${jdbc.username}" />
       <property name="password" value="${jdbc.password}" />
       <!-- 
           <property name="initialSize" value="10" />
           <property name="maxActive" value="50" />
       -->
    </bean>
 
    <!-- Use JNDI dataSource -->
    <!--
       <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
       <property name="jndiName" value="java:comp/env/jdbc/neo"/>
       </bean>
    
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
       <property name="dataSource" ref="dataSource" />
    </bean>
    -->
    
    
    <bean id="jdbcTemplate" class="ssf.teachSys.service.TeachSysJdbcTemplate">
       <property name="dataSource" ref="dataSource" />
    </bean>
 
    
    <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
       <constructor-arg ref="dataSource" />
    </bean>
 
    <bean id="callableStatementTemplate" class="ssf.core.common.CallableStatementTemplate">
       <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>
 
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <property name="dataSource">
           <ref bean="dataSource" />
       </property>
    </bean>
 
    <bean id="baseTxService" 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="query*">PROPAGATION_REQUIRED,readOnly</prop>
              <prop key="save*">PROPAGATION_REQUIRED</prop>
              <prop key="delete*">PROPAGATION_REQUIRED</prop>
              <prop key="fetch*">PROPAGATION_REQUIRED</prop>
              <prop key="rank*">PROPAGATION_REQUIRED</prop>
           </props>
       </property>
    </bean>
</beans>

 

2、利用继承简化配置

 

大部分情况下,每个事务代理的事务属性大同小异,事务代理的实现类都是TransactionProxyFactoryBean,事务代理bean都必须注入事务管理器

 

对于这种情况,spring 提供了bean与bean 之间的继承,可以简化配。将大部分的通用配置,配置成事务模板,而实际事务代理bean,则继承事务模板,这种配置方式可以减少部分配置代码,下面是采用继承的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans default-autowire="byName" default-merge="true">
    
    <bean id="functionService" parent="baseTxService">
       <property name="target">
           <bean class="ssf.teachSys.service.FunctionService" />
       </property>
    </bean>
</beans>