1、什么是事務(wù)
事務(wù)和數(shù)據(jù)庫操作有關(guān),commit事務(wù)提交,rollback事務(wù)回滾
事務(wù)作用:保證一組和數(shù)據(jù)庫有關(guān)的操作的完整性
try{
開啟事務(wù)
操作1--》db操作
操作2--》db操作
操作3--》db操作
提交事務(wù)
}catch{
回滾事務(wù)
}
2、jdbc事務(wù)管理
jdbc事務(wù)管理默認(rèn)提交,每執(zhí)行一個executeUpdate()方法會自動commit或出現(xiàn)異常rollback
若想將多個操作放在同一事物下,需要手動設(shè)置:如轉(zhuǎn)賬
3、Mybatis框架(單獨(dú)使用)
默認(rèn)沒有自動提交,需要執(zhí)行sqlSession.commit();
4、與spring結(jié)合
jdbc和Mybatis與spring結(jié)合,默認(rèn)是一個db操作就自動提交(一個操作屬于一個事務(wù))
如果多個需要將多個操作綁定成一個整體,就需要spring事務(wù)管理(即多個操作放在同一個事務(wù)中,如轉(zhuǎn)賬)
spring事務(wù)管理有以下兩種方式:
a\聲明式事務(wù)管理(基于配置)
----注解配置(更簡單,靈活,打包后(class文件),需修改,需要修改源碼,分散不易管理)
----xml配置(繁瑣,耦合度更低)便于維護(hù)
b\編程式事務(wù)管理(基于Java編寫,TransactionTemplate)
不利于整體配置,很少使用
spring事務(wù)特性
a\讀寫(查 增刪改)
默認(rèn)可讀寫 readOnly=false
若只有查詢,建議使用只讀模式 readonly=true
b\回滾
默認(rèn)運(yùn)行時異?;貪L,檢查時異常不回滾
對于檢查時異??梢酝ㄟ^注解和配置指明
@Transactional(rollbackFor=IOException.class)
對于自定義異常
不會回滾 需要注明roolbackFor=MyException
public class MyException extends Exception()
//回滾,建議
public class MyException extends RuntimeException()
c\傳播
默認(rèn)情況是REQUIRED,可以使用propagation=Propagation.類型
配置
若f1有事務(wù),則f2使用和f1相同的事務(wù),這樣做,f1和f2在同一事務(wù)中,操作3,4出現(xiàn)異常,1,2會回滾,否則就給f2(3,4)創(chuàng)建一個事務(wù)
@Transatioanl
public void f1(){
處理1;
處理2;
f2();
}
@Transatioanl
public void f1(){
處理3;
處理4;
}
d\隔離
對相同的數(shù)據(jù)進(jìn)行讀寫時,事務(wù)并發(fā)會發(fā)生錯誤數(shù)據(jù)處理,會產(chǎn)生臟讀、幻讀,不可重復(fù)讀等錯誤,這些可以通過設(shè)置事務(wù)的隔離級別來解決
臟讀:一個事務(wù)讀取了另一個事務(wù)改寫但還未提交的數(shù)據(jù),如果這些數(shù)據(jù)被回滾,則讀到的數(shù)據(jù)時無效的
不可重復(fù)讀:在同一事務(wù)中,多次讀取同一數(shù)據(jù)返回的結(jié)果不同,換句話說,后續(xù)讀取可以讀到另一事務(wù)已提交的更新數(shù)據(jù),這樣就會出現(xiàn)兩次讀取數(shù)據(jù)不一樣(如事務(wù)t1讀取某一數(shù)據(jù),事務(wù)t2讀取并修改了該數(shù)據(jù),t1為了讀取值驚醒校驗而在此讀取改數(shù)據(jù),得到了不同的結(jié)果)
可重復(fù)讀:在同一事務(wù)中多次讀取數(shù)據(jù)時,能夠保證所讀數(shù)據(jù)一樣,也就是后續(xù)讀取不能讀到另一事務(wù)已經(jīng)提交更新的數(shù)據(jù)
幻讀:一個事務(wù)讀取了幾行記錄后,另一事務(wù)插入一些記錄,幻讀就發(fā)生了,再后來的查詢中,第一個事務(wù)就會發(fā)現(xiàn)原來沒有的記錄
隔離級別(isolation):
1、讀未提交 READ_UNCOMMITTED 還未提交就能查看
2、讀已提交 READ_COMMITTED 這個級別會把查看,增刪改隔離開來,未提交的增刪改不能查看
3、可重復(fù)讀REPEATABLE_READ
4、序列化操作SERIALIZABLE 事務(wù)間對同一數(shù)據(jù)互斥,必須等第一個事物完成之后,第二個事務(wù)才可以操作
默認(rèn)值 DEFAULT(oracle 默認(rèn)值是第二個,mysql是第三個)
隔離級別由低到高的順序 READ_UNCOMMITTED -->READ_COMMITTED-->REPEATABLE_READ-->SERIALIZABLE級別越高安全性越高,并發(fā)處理能力越低
@Transactional(isolation=isolation.READ_COMMITED)
public void f3(){
處理1
處理2
}
spring
一、基于注解方式實(shí)現(xiàn)spring聲明式事務(wù)控制
step1、在主applicationContext配置如下:
<bean id="txManager" class="org.springframework.jdbc.datasource.DatasourceTransaManager“>
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven
proxy-target-class="true"
transaction-manager="txManager"/>
step2、在方法前、類前添加注解@Transactional
添加在方法上的優(yōu)先級高于類
step3、事務(wù)屬性設(shè)置(不設(shè)置即為默認(rèn)值)
a、propagation
事務(wù)的傳播屬性(默認(rèn)即可):PROPATION.REQUIRED
b、isolation
事務(wù)的隔離級別(默認(rèn)):ISOLATION.DEFAULT
c、readOnly
事務(wù)的只讀模式:默認(rèn)是false
d、rollback
遇到什么類型的異常,需要回滾
e、noRollback
遇到什么類型的異常不需要回滾
二、基于xml配置
step1、在主applicationContext配置如下:
<bean id="txManager" class="org.springframework.jdbc.datasource.DatasourceTransaManager“>
<property name="dataSource" ref="dataSource"/>
</bean>
step2:xml配置聲明事務(wù)的范圍及類型:定義通知,通知中要處理的就是事務(wù)
<tx:advice id="txAdvice" transaction-manager="txManager"/>
step3、配置事務(wù)的屬性
<tx:attributes>
a、propagation
事務(wù)的傳播屬性(默認(rèn)即可):PROPATION.REQUIRED
b、isolation
事務(wù)的隔離級別(默認(rèn)):ISOLATION.DEFAULT
c、readOnly
事務(wù)的只讀模式:默認(rèn)是false
d、rollback
遇到什么類型的異常,需要回滾
e、noRollback
遇到什么類型的異常不需要回滾
<tx:method name="save" propagation="REQUIRD"
isolation="default”
readonly=“false”
rollback-for="Java.lang.IOException"/>
<tx:method name="find*" />
<tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true”>
<aop:pointcut
expression="" id="txPoint">
<aop:adviso advice-ref="txAdvice" pointcut-ref="txPoint"/>
</aop>