1. 程式人生 > >Spring入門學習(基於XML檔案的方式配置事務) 第二十一節

Spring入門學習(基於XML檔案的方式配置事務) 第二十一節

Spring入門學習(基於XML檔案的方式配置事務)

XML方式配置事務

  1. 複製之前的包,去掉相關的註解,新建Spring配置檔案如下:
    <?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:context="http://www.springframework.org/schema/context"
    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-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"
    >
    <!-- 匯入資原始檔 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 配置c3p0資料來源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"></property> <property name="password"
    value="${jdbc.password}">
    </property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property> </bean> <!-- 配置Spring的JdbcTemplete --> <bean id="jdbcTemplete" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置Bean --> <bean id="bookShopDao" class="com.fafa.spring.tx.xml.BookShopDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplete"></property> </bean> <bean id="bookShopService" class="com.fafa.spring.tx.xml.BookShopServiceImpl"> <property name="bookShopDao" ref="bookShopDao"></property> </bean> <bean id="cashier" class="com.fafa.spring.tx.xml.CashierImpl"> <property name="bookShopService" ref="bookShopService"></property> </bean> </beans>
    測試方法如下:
    public class SpringTransactionTest {
    
    	private ApplicationContext ctx = null;
    	private BookShopDao bookShopDao = null;
    	private BookShopService bookShopService = null;
    	private Cashier cashier = null;
    	
    	{
    		ctx = new ClassPathXmlApplicationContext("classpath:applicationContext-tx-xml.xml");
    		bookShopDao = ctx.getBean(BookShopDao.class);
    		bookShopService = ctx.getBean(BookShopService.class);
    		cashier = ctx.getBean(Cashier.class);
    	}
    	
    	@Test
    	public void testBookShopService() {
    		bookShopService.purchase("AA", "1001"); 
    	}
    	
    	@Test
    	public void testTansactionPropagation() {
    		cashier.checkout("AA", Arrays.asList("1001","1002"));
    	}
    
    }
    
    此時設定餘額為30,兩本書的庫存為10本,執行testBookShopService後由於目前還沒有事務控制,所以提示餘額不足後,1001的庫存仍然會減1。
    在這裡插入圖片描述在這裡插入圖片描述在這裡插入圖片描述在這裡插入圖片描述
  2. 新增事務管理
    <!-- 1.配置事務管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	<property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 2.配置事務屬性(隔離級別,只讀) -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    	<tx:attributes>
    		<tx:method name="*"/>
    	</tx:attributes>		
    </tx:advice>
    
    <!-- 3.配置事務切入點及把事務切入點和事務屬性關聯起來 -->
    <aop:config>
    	<aop:pointcut expression="execution(* com.fafa.spring.tx.xml.BookShopService.*(..))" 
    		id="txPointCut"/>
    	<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
    
    再次執行testBookShopService方法後,由於事務管理,所以當餘額不足時,事務會發生回滾,庫存不變。
  3. 修改包結構如下(記得修改xml檔案中引入的包名):
    在這裡插入圖片描述
    事務的切點可以修改如下:
    <!-- 3.配置事務切入點及把事務切入點和事務屬性關聯起來 -->
    <aop:config>
    	<aop:pointcut expression="execution(* com.fafa.spring.tx.xml.service.*.*(..))" 
    		id="txPointCut"/>
    	<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
    
  4. 測試
    修改餘額為300,庫存都為10,執行testTansactionPropagation方法購買兩本書:
    購買成功,餘額-170,庫存各自-1。
    在這裡插入圖片描述在這裡插入圖片描述
  5. 我們再測試事務的傳播屬性,為purchase方法新增屬性,修改配置如下:
    <!-- 2.配置事務屬性(隔離級別,只讀) -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    	<tx:attributes>
    		<!-- 根據方法名指定事務的屬性 -->
    		<tx:method name="purchase" propagation="REQUIRES_NEW"/>
    		<tx:method name="get*" read-only="true"/>
    		<tx:method name="find*" read-only="true"/>
    		<tx:method name="*"/>
    	</tx:attributes>		
    </tx:advice>
    
    測試再來測試testTansactionPropagation方法:
    結果為餘額不變,1001的庫存-1。
    在這裡插入圖片描述在這裡插入圖片描述