1. 程式人生 > >14 Spring框架的事務管理

14 Spring框架的事務管理

  • 通過手動編寫程式碼的方式完成事務的管理

1.配置DataSourceTransactionManager事務管理器傳入資料庫連線池屬性dataSource

2.配置TransactionTemplate事務模板傳入事務管理器屬性DataSourceTransactionManager

3.在需要使用事務的類中注入事務模板

4.使用事務模板的execute方法傳入回撥函式TransactionCallbackWithoutResult介面的匿名內部類或實現類

5.實現TransactionCallbackWithoutResult介面的方法doInTransactionWithoutResult將業務邏輯丟到裡面即可

配置檔案

<?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: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.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx.xsd">
	
	<!-- 手動完成事務管理 -->
	
	
	<!-- 配置datasource C3P0 屬性name值與JDBC不同需要注意-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    	<property name="driverClass" value="com.mysql.jdbc.Driver"/>
    	<property name="jdbcUrl" value="jdbc:mysql:///spring_day03"/>
    	<property name="user" value="root"/>
    	<property name="password" value="Aa123456"/>
    </bean>
	
	<!-- 注入dataSource,持久層繼承jdbcdaosupport,這裡只傳連線池就可以 -->
	<bean id="accountDao" class="demo1.AccountDaoImpl">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	<!-- 注入dao -->
	<bean id="accountService" class="demo1.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"/>
	</bean>
	
	<!-- 配置事務管理器,注入資料庫連線池 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>	
	<!-- 配置事務模板,注入事務管理器 -->
	<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="transactionManager"></property>
	</bean>
	
	
	
</beans>

需使用事務的類

package demo1;

import javax.annotation.Resource;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

public class AccountServiceImpl implements AccountService {

	
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	
	
	/**
	 * #演示手動處理事務
	 */
	@Resource(name="transactionTemplate")
	private TransactionTemplate transactionTemplate;
	
	
	public void pay1(String out, String in, double money) {
		//執行TransactionTemplate.execute方法回撥介面使用TransactionCallbackWithoutResult匿名內部類
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			//將執行邏輯放入介面的實現方法中
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				//執行邏輯
				accountDao.outMoney(out, money);
				//模擬異常
				int i = 1 / 0;
				accountDao.inMoney(in, money);				
			}
		});
		

		
	}
	
	
}

測試類
 

package demo1;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:applicationContext.xml")
@ContextConfiguration("classpath:applicationContext2.xml")
public class Demo {

	@Resource(name="accountService")
	private AccountService accountService;

	/*
	 *	測試手動處理事務
	 */
	@Test
	public void run2() {
		accountService.pay1("alex", "alex1", 10000);
	}

	
}

junit報錯

資料庫沒有變化

事務開啟成功。

  • Spring的宣告式事務管理,通過一段配置的方式完成事務的管理(底層採用AOP的技術)。