spring管理事务详解

    技术2025-06-23  14

        测试环境:sturts1.2+spring2.0+jdbc

           数据库:oracle

        之前一直对spring管理事务不是太了解,今天研究学习了总结如下:

         通过spring来管理事务由三个部分组成:分别是DataSource,TransactionManager和代理机制3个部分。无论哪种配置方式,一般变化的只是代理机制这部分。这里我介绍spring管理JDBC的事务方式。

          配置方式如下:

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

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

     

    <!-- 定义一个数据源 -->

     <bean id="dataSource"  class="org.apache.commons.dbcp.BasicDataSource"  destroy-method="close">  <property name="driverClassName"   value="oracle.jdbc.driver.OracleDriver">  </property>  <property name="url"   value="jdbc:oracle:thin:@127.0.0.1:1521:orcl">  </property>  <property name="username" value="new_premain"></property>  <property name="password" value="new_premain"></property> </bean>

     

    <!-- Dao文件统计jdbcTemplate来操作数据库 --> <bean id="jdbcTemplate"  class="org.springframework.jdbc.core.JdbcTemplate">  <property name="dataSource" ref="dataSource"></property> </bean>

     

    <!-- 申明一个事务管理器 -->

     <bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  <property name="dataSource" ref="dataSource"></property> </bean>

     

    <!-- 申明一个事务代理机制  加入abstract让多个业务Bean共享一个事务代理机制,当代理的业务Bean没有实现接口时设置 proxyTargetClass为true 即  Spring代理有两种方式,一种时对接口的代理,另一种是才用CGLIB代理方式,对接口的代理是JDK采用的代理方式,但在没有接口的情况下Srping通过设置proxyTargetClass等于 true来使用CGLIB代理,CGLIB是一种面向继承的代理方式。同时还有一个proxyTarget属性用来指定代理的目标对象类。    

    -->

     

     <bean id="transactionProxyFactoryBean"  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">  <property name="transactionManager" ref="transactionManager"></property>     <property name="proxyTargetClass" value="true" />  <property name="transactionAttributes">   <props>    <prop key="*">PROPAGATION_REQUIRED</prop>   </props>  </property> </bean>

     

     

     <bean id="addSourceDao" class="com.Dao.AddSourceDao">  <property name="dataSource" ref="dataSource"></property> </bean>

     

    <!-- 对应代理的业务Bean继承代理机制 -->

     <bean id="addSourceService" parent="transactionProxyFactoryBean">  <property name="target">   <bean class="com.service.AddSourceService">    <property name="addSourceDao">     <ref bean="addSourceDao" />    </property>   </bean>  </property> </bean>

     <bean name="/login" class="com.struts.action.LoginAction">  <property name="addSourceService" ref="addSourceService"></property> </bean>

    </beans>

     

     

     

    数据库操作代码:

    package com.Dao;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AddSourceDao extends JdbcDaoSupport {

     public void addSchool()  {  String sqlOne = "insert into shools(id,CUSTOMERSID,SHOOLNAME,SHOOLTYPE,TIME) values('123123','123123','武汉理工大学','本科',to_date('2010-09-01','yyyy-mm-dd') )";  String sqlTwo = "insert into shools(id,CUSTOMERSID,SHOOLNAME,SHOOLTYPE,TIME) values('123123','123123','武汉理工大学','本科',to_date('2010-09-012','yyyy-mm-dd') )";    this.getJdbcTemplate().execute(sqlOne);  this.getJdbcTemplate().execute(sqlTwo); }}

     

     

     

    以上的事务管理是通过TransactionProxyFactoryBean代理机制来控制,下面我介绍通过tx/aop来控制事务。

    上面说过了控制事务由DataSource,TransactionManager和代理机制3个部分,那么通过tx/aop来控制事务变化的也就是代理机制的变化。其它什么代码都不需要变化,变化的就是application.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-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd ">

     <bean id="dataSource"  class="org.apache.commons.dbcp.BasicDataSource"  destroy-method="close">  <property name="driverClassName"   value="oracle.jdbc.driver.OracleDriver">  </property>  <property name="url"   value="jdbc:oracle:thin:@127.0.0.1:1521:orcl">  </property>  <property name="username" value="new_premain"></property>  <property name="password" value="new_premain"></property> </bean>

     <bean id="jdbcTemplate"  class="org.springframework.jdbc.core.JdbcTemplate">  <property name="dataSource" ref="dataSource"></property> </bean>

     

     

     <bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  <property name="dataSource" ref="dataSource"></property> </bean>

     

    <!-- 这里就是变化的地方。它通知事务管理器 -->

     <tx:advice id="txAdvice" transaction-manager="transactionManager">  <tx:attributes>   <tx:method name="add*" propagation="REQUIRED" />  </tx:attributes> </tx:advice>

     

     

     <aop:config>

         <!-- 指明AOP的切点 -->       <aop:pointcut id="allManagerMethod"           expression="execution(* com.service.AddSourceService.*(..))" />       <aop:advisor advice-ref="txAdvice"            pointcut-ref="allManagerMethod" /><!-- 引用事务管理器来管理切入点的事务 -->

         </aop:config>

     

     <bean id="addSourceDao" class="com.Dao.AddSourceDao">       <property name="dataSource" ref="dataSource"></property> </bean>

     

     <bean id="addSourceService" class="com.service.AddSourceService">  <property name="addSourceDao" ref="addSourceDao"></property>   </bean>

     

    <bean name="/login" class="com.struts.action.LoginAction">  <property name="addSourceService" ref="addSourceService"></property> </bean>

     

    </beans>

     

    通过tx/aop来管理事务更加方便。注意execution(* com.service.*.*(..))  里面第一个*表示返回参数为任意类型,第二个

    表示service包下的任意类,第三个*表示任意方法。括号里面的..表示方法里面的参数为任意多个参数。

    好了tx/aop管理事务的配置就写完了很简单吧

     

     

     

    最新回复(0)