[Spring框架]Spring 事務管理基礎入門總結.
前言:
在之前的博客中已經說過了數據庫的事務, 不過那裏面更多的是說明事務的一些鎖機制, 今天來說一下Spring管理事務的一些基礎知識.
之前的文章: [數據庫事務與鎖]詳解一: 徹底理解數據庫事務
一, 什麽是事務
事務是邏輯上一組操作,這組操作要麽全都成功,要麽全都失敗.
事務的屬性: ACID
原子性(Atomicity): 事務作為一個整體被執行,包含在其中的對數據的操作要麽全部被執行,要麽都不執行.
一致性(Consistency):事務應確保數據庫的狀態從一個一致狀態轉變為另一個一致狀態. 一致狀態的含義是數據庫中的數據應滿足為完整性約束.
隔離性(Isolation):多個事務並發執行時, 一個事務的執行不應該影響其他事務的執行.
持久性(Durability):一個事務一旦提交, 他對數據庫的修改應該永久保存在數據庫中.
二, Spring的事務管理
一類:編程式事務管理.手動編寫代碼管理事務.
二類:聲明式事務管理.通過配置完成事務管理.(AOP) : 這裏只說聲明式的事務管理.
事務管理的API:
PlatformTransactionManager :平臺事務管理器
* 是真正管理事務的對象.
TransactionDefinition :事務定義信息.
* 定義事務的(隔離級別,傳播行為,超時信息,只讀)
TransactionStatus :事務狀態.
* 管理事務的過程中,事務有一些狀態的改變.狀態信息被記錄在該對象中.
Spring根據TransactionDefinition中定義的信息使用PlatformTransactionManager管理事務,管理事務過程中產生狀態,將狀態記錄到TransactionStatus中.
三, Spring相關API詳解
1,PlatformTransactionManager
2,TransactionDefinition
常量:
* ISOLATION_*:定義事務的隔離級別.
* PROPAGATION_*:定義事務的傳播行為.
* 超時信息:
方法:
Transaction事務狀態:
|
Spring的事務傳播行為:
PROPAGATION_REQUIRED :如果A,B操作,如果A有事務使用A的事務將B包含進來.如果A沒有事務創建一個新事務將A,B包進來. PROPAGATION_SUPPORTS :如果A,B操作,如果A有事務,使用A的事務將B包含進來.如果A沒有事務,不使用事務. PROPAGATION_MANDATORY :如果A,B操作,如果A有事務,使用A的事務將B包含進來.如果A沒有事務,就會拋出異常. PROPAGATION_REQUIRES_NEW :如果A,B操作,如果A有事務,將A的事務掛起.創建一個新事務執行B操作. PROPAGATION_NOT_SUPPORTED :如果A,B操作,總是以非事務方式運行,如果A有,將A掛起. PROPAGATION_NEVER :如果A,B操作,總是以非事務方式運行,如果A有事務拋出異常. PROPAGATION_NESTED :嵌套事務.如果A,B操作,A有事務,在A執行完之後設置一個保存點.如果B執行沒有問題,一起提交.如果B出現問題.允許用戶自己控制回滾到最初還是回滾到保存點.
四, Spring事務管理實例(聲明式事務管理)
Spring聲明式事務管理又可分為三種:
1,基於TransactionProxyFactoryBean
2, 基於AspectJ的XML方式的事務管理
3, 基於AspectJ的註解方式事務管理
基於AspectJ的XML方式的事務管理:
1,引入開發包:
2,Service層代碼:
AccountService.java
1 public interface AccountService { 2 3 /** 4 * 轉賬的方法 5 */ 6 public void transfer(String from,String to,Double money); 7 }
AccountServiceImpl.java:
1 private AccountDao accountDao; 2 3 public void setAccountDao(AccountDao accountDao) { 4 this.accountDao = accountDao; 5 } 6 7 @Override 8 /** 9 * 業務層轉賬的方法: 10 * from:轉出賬號 11 * to:轉入賬號 12 * money:轉賬金額 13 */ 14 public void transfer(final String from, final String to, final Double money) { 15 accountDao.outMoney(from, money); 16 int d = 1 / 0; 17 accountDao.inMoney(to, money); 18 } 19 20 }
3,DAO層代碼
AccountDAO.java:
1 public interface AccountDao { 2 public void outMoney(String from, Double money); 3 4 public void inMoney(String to, Double money); 5 }
AccountDAOImpl.java:
1 public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { 2 3 @Override 4 public void outMoney(String from, Double money) { 5 this.getJdbcTemplate().update("update account set money = money - ? where name = ?", money,from); 6 } 7 8 @Override 9 public void inMoney(String to, Double money) { 10 this.getJdbcTemplate().update("update account set money = money + ? where name = ?", money,to); 11 } 12 13 }
4,配置文件
jdbc.properties:
jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///spring_transaction jdbc.user=root jdbc.password=123
applicationcontext.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:aop="http://www.springframework.org/schema/aop" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/context 10 http://www.springframework.org/schema/context/spring-context.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx/spring-tx.xsd"> 15 16 <context:property-placeholder location="classpath:jdbc.properties"/> 17 18 <!-- 配置C3P0連接池 --> 19 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 20 <property name="driverClass" value="${jdbc.driverClass}"/> 21 <property name="jdbcUrl" value="${jdbc.url}"/> 22 <property name="user" value="${jdbc.user}"/> 23 <property name="password" value="${jdbc.password}"/> 24 </bean> 25 <!-- 配置Service --> 26 <bean id="accountService" class="cn.augmentum.transaction.demo3.service.AccountServiceImpl"> 27 <property name="accountDao" ref="accountDao"/> 28 </bean> 29 30 <!-- 配置DAO --> 31 <bean id="accountDao" class="cn.augmentum.transaction.demo3.dao.AccountDaoImpl"> 32 <property name="dataSource" ref="dataSource"/> 33 </bean> 34 35 <!-- 配置事務管理器 --> 36 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 37 <property name="dataSource" ref="dataSource"/> 38 </bean> 39 40 <!-- 配置事務增強 --> 41 <tx:advice id="txAdvice" transaction-manager="transactionManager"> 42 <tx:attributes> 43 <!-- 44 propagation:事務傳播行為: 45 isolation:隔離級別 46 read-only:是否為只讀事務. 47 timeout :是否超時. 48 rollback-for:類似-Exception.發生哪些異常回滾事務. 49 no-rollback-for:類似+Exception.發生哪些異常不回滾. 50 --> 51 <tx:method name="transfer" propagation="REQUIRED"/> 52 </tx:attributes> 53 </tx:advice> 54 55 56 <!-- AOP的配置 --> 57 <aop:config> 58 <aop:pointcut expression="execution(* cn.augmentum.transaction.demo3.service.AccountServiceImpl.*(..))" id="pointcut1"/> 59 <aop:advisor advice-ref="txAdvice" pointcut-ref=""/> 60 </aop:config> 61 </beans>
5, 測試方法
SpringDemo.java:
1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration("classpath:applicationContext.xml") 3 public class SpringDemo3 { 4 5 @Resource(name="accountService") 6 private AccountService accountService; 7 8 @Test 9 public void demo1(){ 10 accountService.transfer("老馬", "鳳姐", 1000d); 11 } 12 }
關於XML的聲明式事務管理就這些了, 那麽下面來看下更簡單的關於註解的聲明式事務管理的做法.;
這裏只需要看Service層是如何加註解以及applicationcontext中是怎樣配置的就行了.
AccountServiceImpl.java:
1 /** 2 * @Transactional中屬性 3 * propagation:傳播行為. 4 * readOnly:是否只讀 5 * timeout:超時信息 6 * isolation:隔離級別 7 */ 8 @Transactional(propagation=Propagation.REQUIRED,readOnly=false,timeout=-1,isolation=Isolation.DEFAULT) 9 public class AccountServiceImpl implements AccountService { 10 private AccountDao accountDao; 11 12 public void setAccountDao(AccountDao accountDao) { 13 this.accountDao = accountDao; 14 } 15 16 @Override 17 /** 18 * 業務層轉賬的方法: 19 * from:轉出賬號 20 * to:轉入賬號 21 * money:轉賬金額 22 */ 23 public void transfer(final String from, final String to, final Double money) { 24 accountDao.outMoney(from, money); 25 int d = 1 / 0; 26 accountDao.inMoney(to, money); 27 } 28 }
applicationcontext.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:aop="http://www.springframework.org/schema/aop" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/context 10 http://www.springframework.org/schema/context/spring-context.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx/spring-tx.xsd"> 15 16 <context:property-placeholder location="classpath:jdbc.properties"/> 17 18 <!-- 配置C3P0連接池 --> 19 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 20 <property name="driverClass" value="${jdbc.driverClass}"/> 21 <property name="jdbcUrl" value="${jdbc.url}"/> 22 <property name="user" value="${jdbc.user}"/> 23 <property name="password" value="${jdbc.password}"/> 24 </bean> 25 <!-- 配置Service --> 26 <bean id="accountService" class="cn.augmentum.transaction.demo4.service.AccountServiceImpl"> 27 <property name="accountDao" ref="accountDao"/> 28 </bean> 29 30 <!-- 配置DAO --> 31 <bean id="accountDao" class="cn.augmentum.transaction.demo4.dao.AccountDaoImpl"> 32 <property name="dataSource" ref="dataSource"/> 33 </bean> 34 35 <!-- 配置事務管理器 --> 36 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 37 <property name="dataSource" ref="dataSource"/> 38 </bean> 39 40 <!-- 開啟註解事務 --> 41 <tx:annotation-driven transaction-manager="transactionManager"/> 42 </beans>
註解方式的聲明式事務管理也就是這麽多, 看起來確實簡單了很多.
[Spring框架]Spring 事務管理基礎入門總結.