接着上一节内容,把注解配置@@Transactional形式改为xml配置形式;
1 <!-- 1配置事务管理器 --> 2 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 3 <property name="dataSource" ref="datasource1"></property> 4 </bean>
1 <!-- 根据方法名,指定事务的属性,若不指定,则方法名用*代替 --> 2 <tx:advice id="txAdive" transaction-manager="transactionManager"> 3 <tx:attributes> 4 <tx:method name="purchase" propagation="REQUIRED"/> 5 </tx:attributes> 6 </tx:advice>
1 <!-- 3配置事务切点 --> 2 <aop:config> 3 <aop:pointcut expression="execution(public void lixiuming.spring.tx.xml.service.*.*(..))" id="txpointcut" /> 4 <aop:advisor advice-ref="txAdive" pointcut-ref="txpointcut"/> 5 </aop:config>
execution(public void lixiuming.spring.tx.xml.service.*.*(..)) 的说明 ,详见三(二)、AOP配置
附上xml文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xmlns:aop="http://www.springframework.org/schema/aop" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 9 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 10 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> 11 12 13 <!-- 配置测试ContactsDao --> 14 <!-- <context:component-scan base-package="lixiuming.spring.jdbc"></context:component-scan> --> 15 <context:component-scan base-package="lixiuming.spring.tx.xml"></context:component-scan> 16 17 <!-- 导入资源文件 --> 18 <context:property-placeholder location="classpath:db.properties"/> 19 <!-- 配置c3p0数据源 --> 20 <bean id="datasource1" class="com.mchange.v2.c3p0.ComboPooledDataSource" > 21 <property name="user" value="${jdbc.user}"></property> 22 <property name="password" value="${jdbc.password}"></property> 23 <property name="driverClass" value="${jdbc.driverClass}"></property> 24 <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> 25 26 <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property> 27 <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property> 28 <property name="maxStatements" value="${jdbc.maxStatements}"></property> 29 </bean> 30 31 32 <!-- 配置 NamedParameterJdbcTemplate 该对象可以使用具名参数 他没有无参数的构造器,必须指定构造器参数--> 33 <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> 34 <constructor-arg ref="datasource1"></constructor-arg> 35 </bean> 36 37 <!--配置spring的 jdbcTemplate --> 38 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 39 <property name="dataSource" ref="datasource1"></property> 40 </bean> 41 <!-- 配置bean --> 42 <bean id="bookShop" class="lixiuming.spring.tx.xml.BookShopImpl"> 43 <property name="jdbcTemplate" ref="jdbcTemplate"></property> 44 </bean> 45 46 <bean id="bookShopService" class="lixiuming.spring.tx.xml.service.impl.BookShopServiceImpl"> 47 <property name="dao" ref="bookShop"></property> 48 </bean> 49 50 <bean id="cashier" class="lixiuming.spring.tx.xml.service.impl.CashierImpl"> 51 <property name="service" ref="bookShopService"></property> 52 </bean> 53 <!-- 1配置事务管理器 --> 54 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 55 <property name="dataSource" ref="datasource1"></property> 56 </bean> 57 58 <!--2 配置事务属性 --> 59 <!-- 根据方法名,指定事务的属性,若不指定,则方法名用*代替 --> 60 <tx:advice id="txAdive" transaction-manager="transactionManager"> 61 <tx:attributes> 62 <tx:method name="purchase" propagation="REQUIRED"/> 63 </tx:attributes> 64 </tx:advice> 65 66 <!-- 3配置事务切点 --> 67 <aop:config> 68 <aop:pointcut expression="execution(public void lixiuming.spring.tx.xml.service.*.*(..))" id="txpointcut" /> 69 <aop:advisor advice-ref="txAdive" pointcut-ref="txpointcut"/> 70 </aop:config> 71 72 73 74 </beans>
1 package lixiuming.spring.tx.xml; 2 3 import java.util.Arrays; 4 5 import org.junit.Test; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 9 import lixiuming.spring.tx.xml.service.BookShopService; 10 import lixiuming.spring.tx.xml.service.Cashier; 11 12 public class SpringTransactionTest { 13 14 private ApplicationContext cxt = null; 15 private BookShopService parchase = null; 16 private Cashier c = null; 17 18 { 19 cxt = new ClassPathXmlApplicationContext("applicationcontext22.xml"); 20 parchase = (BookShopService) cxt.getBean("bookShopService"); 21 c = (Cashier) cxt.getBean("cashier"); 22 } 23 24 @Test 25 public void testCheckout() { 26 c.checkout("aa", Arrays.asList(1001, 1001)); 27 28 } 29 30 @Test 31 public void testpurchase() { 32 parchase.purchase("aa", 1001); 33 } 34 35 }
测试:
测试前提:用户账户表 账户金额为120 ; 书号1001和1002的图书库存为 10 ;购买第一本书时,账户余额是够的,但是第二本书钱不够;
当第一次运行testCheckout时,报错为余额不足; 书号1001和1002的图书库存为 还是为10;用户账户表 账户金额为120 ;