spring教程--事务管理
Spring的事務(wù)管理
1.1?事務(wù):
事務(wù):是邏輯上一組操作,要么全都成功,要么全都失敗.
事務(wù)特性:
ACID:
原子性:事務(wù)不可分割
一致性:事務(wù)執(zhí)行的前后,數(shù)據(jù)完整性保持一致.
隔離性:一個(gè)事務(wù)執(zhí)行的時(shí)候,不應(yīng)該受到其他事務(wù)的打擾
持久性:一旦結(jié)束,數(shù)據(jù)就永久的保存到數(shù)據(jù)庫.
如果不考慮隔離性:
臟讀:一個(gè)事務(wù)讀到另一個(gè)事務(wù)未提交數(shù)據(jù)
不可重復(fù)讀:一個(gè)事務(wù)讀到另一個(gè)事務(wù)已經(jīng)提交數(shù)據(jù)(update)導(dǎo)致一個(gè)事務(wù)多次查詢結(jié)果不一致
虛讀:一個(gè)事務(wù)讀到另一個(gè)事務(wù)已經(jīng)提交數(shù)據(jù)(insert)導(dǎo)致一個(gè)事務(wù)多次查詢結(jié)果不一致
事務(wù)的隔離級(jí)別:
未提交讀:以上情況都有可能發(fā)生。
已提交讀:避免臟讀,但不可重復(fù)讀,虛讀是有可能發(fā)生。
可重復(fù)讀:避免臟讀,不可重復(fù)讀,但是虛讀有可能發(fā)生。
串行的:避免以上所有情況.
1.2?Spring中事務(wù)管理:
分層開發(fā):事務(wù)處在Service層.
Spring提供事務(wù)管理API:
PlatformTransactionManager:平臺(tái)事務(wù)管理器.
PROPAGATION_XXX:事務(wù)的傳播行為.(不是JDBC中有的,為了解決實(shí)際開發(fā)問題.)
過期時(shí)間:
TransactionStatus:事務(wù)狀態(tài)
是否有保存點(diǎn)
是否一個(gè)新的事務(wù)
事務(wù)是否已經(jīng)提交
關(guān)系:PlatformTransactionManager通過TransactionDefinition設(shè)置事務(wù)相關(guān)信息管理事務(wù),管理事務(wù)過程中,產(chǎn)生一些事務(wù)狀態(tài):狀態(tài)由TransactionStatus記錄.
API詳解:
PlatformTransactionManager:接口.
Spring為不同的持久化框架提供了不同PlatformTransactionManager接口實(shí)現(xiàn)
org.springframework.jdbc.datasource.DataSourceTransactionManager:使用Spring JDBC或iBatis 進(jìn)行持久化數(shù)據(jù)時(shí)使用
org.springframework.orm.hibernate3.HibernateTransactionManager: 使用Hibernate3.0版本進(jìn)行持久化數(shù)據(jù)時(shí)使用
org.springframework.orm.jpa.JpaTransactionManager使用JPA進(jìn)行持久化時(shí)使用
org.springframework.jdo.JdoTransactionManager當(dāng)持久化機(jī)制是Jdo時(shí)使用
org.springframework.transaction.jta.JtaTransactionManager使用一個(gè)JTA實(shí)現(xiàn)來管理事務(wù),在一個(gè)事務(wù)跨越多個(gè)資源時(shí)必須使用
TransactionDefinition:
* ISOLATION_DEFAULT:默認(rèn)級(jí)別. Mysql ?repeatable_readoracle read_commited
* 事務(wù)的傳播行為:(不是JDBC事務(wù)管理,用來解決實(shí)際開發(fā)的問題.)傳播行為:解決業(yè)務(wù)層之間的調(diào)用的事務(wù)的關(guān)系.
PROPAGATION_REQUIRED:支持當(dāng)前事務(wù),如果不存在 就新建一個(gè)
* A,B如果A有事務(wù),B使用A的事務(wù),如果A沒有事務(wù),B就開啟一個(gè)新的事務(wù).(A,B是在一個(gè)事務(wù)中。)
PROPAGATION_SUPPORTS:支持當(dāng)前事務(wù),如果不存在,就不使用事務(wù)
* A,B如果A有事務(wù),B使用A的事務(wù),如果A沒有事務(wù),B就不使用事務(wù).
PROPAGATION_MANDATORY:支持當(dāng)前事務(wù),如果不存在,拋出異常
* A,B如果A有事務(wù),B使用A的事務(wù),如果A沒有事務(wù),拋出異常.
PROPAGATION_REQUIRES_NEW:如果有事務(wù)存在,掛起當(dāng)前事務(wù),創(chuàng)建一個(gè)新的事務(wù)
* A,B如果A有事務(wù),B將A的事務(wù)掛起,重新創(chuàng)建一個(gè)新的事務(wù).(A,B不在一個(gè)事務(wù)中.事務(wù)互不影響.)
PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式運(yùn)行,如果有事務(wù)存在,掛起當(dāng)前事務(wù)
* A,B非事務(wù)的方式運(yùn)行,A有事務(wù),就會(huì)掛起當(dāng)前的事務(wù).
PROPAGATION_NEVER: 以非事務(wù)方式運(yùn)行,如果有事務(wù)存在,拋出異常
PROPAGATION_NESTED: 如果當(dāng)前事務(wù)存在,則嵌套事務(wù)執(zhí)行
* 基于SavePoint技術(shù).
* A,BA有事務(wù),A執(zhí)行之后,將A事務(wù)執(zhí)行之后的內(nèi)容保存到SavePoint.B事務(wù)有異常的話,用戶需要自己設(shè)置事務(wù)提交還是回滾.
常用:
PROPAGATION_REQUIRED
PROPAGATION_REQUIRES_NEW
PROPAGATION_NESTED
1.3?Spring的事務(wù)管理:
Spring的事務(wù)管理分成兩類:
* 編程式事務(wù)管理:
* 手動(dòng)編寫代碼完成事務(wù)管理.
* 聲明式事務(wù)管理:
* 不需要手動(dòng)編寫代碼,配置.
1.4?事務(wù)操作的環(huán)境搭建:
CREATE TABLE `account` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) NOT NULL,`money` double DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;INSERT INTO `account` VALUES ('1', 'aaa', '1000');INSERT INTO `account` VALUES ('2', 'bbb', '1000');INSERT INTO `account` VALUES ('3', 'ccc', '1000');1.4.1 創(chuàng)建一個(gè)web項(xiàng)目:
* 導(dǎo)入相應(yīng)jar包
* 引入配置文件:
* applicationContext.xml、log4j.properties、jdbc.properties
1.4.2 創(chuàng)建類:
* AccountService
* AccountDao
1.4.3 在Spring中注冊(cè):
<!-- 業(yè)務(wù)層類 --><bean id="accountService" class="com.sihai.spring3.demo1.AccountServiceImpl"><!-- 在業(yè)務(wù)層注入Dao --><property name="accountDao" ref="accountDao"/></bean><!-- 持久層類 --><bean id="accountDao" class="com.sihai.spring3.demo1.AccountDaoImpl"><!-- 注入連接池的對(duì)象,通過連接池對(duì)象創(chuàng)建模板. --><property name="dataSource" ref="dataSource"/></bean>1.4.4 編寫一個(gè)測(cè)試類:
package com.sihai.spring3.demo1;import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringTest1 {@Autowired@Qualifier("accountService")private AccountService accountService;@Testpublic void demo1(){// 完成轉(zhuǎn)賬accountService.transfer("aaa", "bbb", 100d);} }1.5?Spring的事務(wù)管理
1.5.1 手動(dòng)編碼的方式完成事務(wù)管理:
需要事務(wù)管理器:真正管理事務(wù)對(duì)象.
* Spring提供了事務(wù)管理的模板(工具類.)
第一步:注冊(cè)事務(wù)管理器:
<!-- 配置事務(wù)管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 需要注入連接池,通過連接池獲得連接 --><property name="dataSource" ref="dataSource"/></bean>第二步:注冊(cè)事務(wù)模板類:
<!-- 事務(wù)管理的模板 --><bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"><property name="transactionManager" ref="transactionManager"/></bean>第三步:在業(yè)務(wù)層注入模板類:(模板類管理事務(wù))
<!-- 業(yè)務(wù)層類 --><bean id="accountService" class="com.sihai.spring3.demo1.AccountServiceImpl"><!-- 在業(yè)務(wù)層注入Dao --><property name="accountDao" ref="accountDao"/><!-- 在業(yè)務(wù)層注入事務(wù)的管理模板 --><property name="transactionTemplate" ref="transactionTemplate"/></bean>第四步:在業(yè)務(wù)層代碼上使用模板:
public void transfer(final String from, final String to, final Double money) {transactionTemplate.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus status) {accountDao.out(from, money);int d = 1 / 0;accountDao.in(to, money);}});}1.5.2 聲明式事務(wù)管理:(原始方式)
基于TransactionProxyFactoryBean.
導(dǎo)入:aop相應(yīng)jar包.
第一步:注冊(cè)平臺(tái)事務(wù)管理器:
<!-- 事務(wù)管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 注入連接池 --><property name="dataSource" ref="dataSource"/></bean>第二步:創(chuàng)建業(yè)務(wù)層代理對(duì)象:
<!-- 配置生成代理對(duì)象 --><bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><!-- 目標(biāo)對(duì)象 --><property name="target" ref="accountService"/><!-- 注入事務(wù)管理器 --><property name="transactionManager" ref="transactionManager"/><!-- 事務(wù)的屬性設(shè)置 --><property name="transactionAttributes"><props><prop key="transfer">PROPAGATION_REQUIRED</prop></props></property></bean>第三步:編寫測(cè)試類:
package com.sihai.spring3.demo2;import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext2.xml") public class SpringTest2 {@Autowired@Qualifier("accountServiceProxy")private AccountService accountService;@Testpublic void demo1(){accountService.transfer("aaa", "bbb", 100d);} }1.5.3 聲明式事務(wù)管理:(自動(dòng)代理.基于切面)
第一步:導(dǎo)入相應(yīng)jar包.
?aspectj
第二步:引入相應(yīng)約束:
?aop、tx約束.
<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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/tx" >http://www.springframework.org/schema/tx/spring-tx.xsd">第三步:注冊(cè)事務(wù)管理器;
<!-- 事務(wù)管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean>第四步:定義增強(qiáng)(事務(wù)管理)
<!-- 定義一個(gè)增強(qiáng) --><tx:advice id="txAdvice" transaction-manager="transactionManager"><!-- 增強(qiáng)(事務(wù))的屬性的配置 --><tx:attributes><!--isolation:DEFAULT:事務(wù)的隔離級(jí)別.propagation:事務(wù)的傳播行為.read-only:false.不是只讀timeout:-1no-rollback-for:發(fā)生哪些異常不回滾rollback-for:發(fā)生哪些異常回滾事務(wù)--><tx:method name="transfer"/></tx:attributes></tx:advice>第五步:定義aop的配置(切點(diǎn)和通知的組合)
<!-- aop配置定義切面和切點(diǎn)的信息 --><aop:config><!-- 定義切點(diǎn):哪些類的哪些方法應(yīng)用增強(qiáng) --><aop:pointcut expression="execution(* com.sihai.spring3.demo3.AccountService+.*(..))" id="mypointcut"/><!-- 定義切面: --><aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/></aop:config>第六步:編寫測(cè)試類:
?注入Service對(duì)象,不需要注入代理對(duì)象(生成這個(gè)類的時(shí)候,已經(jīng)是代理對(duì)象.)
package com.sihai.spring3.demo3;import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /*** 聲明式事務(wù)使用:基于切面的* @author sihai**/ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext3.xml") public class SpringTest3 {@Autowired@Qualifier("accountService")private AccountService accountService;@Testpublic void demo1(){accountService.transfer("aaa", "bbb", 100d);} }1.5.4 基于注解的事務(wù)管理:
第一步:事務(wù)管理器:
<!-- 事務(wù)管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean>第二步:注解事務(wù):
<!-- 開啟注解的事務(wù)管理 --><tx:annotation-driven transaction-manager="transactionManager"/>第三步:在Service上使用注解
package com.sihai.spring3.demo4;import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional;@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false) public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}/*** 轉(zhuǎn)賬的方法* * @param from* :從哪轉(zhuǎn)出* @param to* :轉(zhuǎn)入的人* @param money* :轉(zhuǎn)賬金額*/public void transfer(final String from, final String to, final Double money) {accountDao.out(from, money);//int d = 1 / 0;accountDao.in(to, money);} }第四步:編寫測(cè)試類
package com.sihai.spring3.demo4;import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /*** 聲明式事務(wù)使用:基于切注解的* @author sihai**/ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext4.xml") public class SpringTest4 {@Autowired@Qualifier("accountService")private AccountService accountService;@Testpublic void demo1(){accountService.transfer("aaa", "bbb", 100d);} }總結(jié)
以上是生活随笔為你收集整理的spring教程--事务管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring教程--JdbcTempla
- 下一篇: 【struts2+spring+hibe