spring+mybatis實(shí)現(xiàn)事務(wù)的配置

一、聲明式事務(wù)配置:

(一)申明式事務(wù)配置步驟:

????1、xml文件頭部需要添加spring的相關(guān)支持:


????2、配置事務(wù)管理器

? ? 3、配置需要加入事務(wù)的方法規(guī)則,或者說(shuō)是一個(gè)切面

(二)注解式事務(wù)配置

1、添加注解配置

<!-- 定義事務(wù)管理器 -->?

<bean id="transactionManager"? class="org.springframework.jdbc.datasource.DataSourceTransactionManager">?

? <property name="dataSource" ref="dataSource" />?

</bean>?

<!--使用注釋事務(wù) -->?

<tx:annotation-driven? transaction-manager="transactionManager" />

2、在需要加入事務(wù)的方法或者類上添加@Transactional

事物配置中有哪些屬性可以配置

(1)事務(wù)的傳播性:@Transactional(propagation=Propagation.REQUIRED)?

? ? ? 如果有事務(wù), 那么加入事務(wù), 沒(méi)有的話新建一個(gè)(默認(rèn)情況下)

(2)事務(wù)的超時(shí)性:@Transactional(timeout=30) //默認(rèn)是30秒?

? ? ? 注意這里說(shuō)的是事務(wù)的超時(shí)性而不是Connection的超時(shí)性,這兩個(gè)是有區(qū)別的

(3)事務(wù)的隔離級(jí)別:@Transactional(isolation = Isolation.READ_UNCOMMITTED)

? ? ? 讀取未提交數(shù)據(jù)(會(huì)出現(xiàn)臟讀, 不可重復(fù)讀) 基本不使用

(4)回滾:

指定單一異常類:@Transactional(rollbackFor=RuntimeException.class)

指定多個(gè)異常類:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

該屬性用于設(shè)置需要進(jìn)行回滾的異常類數(shù)組,當(dāng)方法中拋出指定異常數(shù)組中的異常時(shí),則進(jìn)行事務(wù)回滾。

(5)只讀:@Transactional(readOnly=true)

該屬性用于設(shè)置當(dāng)前事務(wù)是否為只讀事務(wù),設(shè)置為true表示只讀,false則表示可讀寫(xiě),默認(rèn)值為false。

例如:

@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,timeout=1,isolation=Isolation.DEFAULT)?

public void saveUser(Map<String, String> map) throws Exception {?

? ? System.out.println("方法開(kāi)始");?

? ? for (int i = 0; i < 500000; i++) {?

? ? ? ? ? ? System.out.println("*");?

? ? ? ? }?

? ? System.out.println("進(jìn)入保存");?

? ? userDao.saveUser(map);?

? ? System.out.println("退出保存");?

}?

解釋說(shuō)明

事務(wù)的傳播級(jí)別定義的是事務(wù)的控制范圍,主要是父子事務(wù)之間的相互影響關(guān)系;事務(wù)的隔離級(jí)別定義的是事務(wù)讀寫(xiě)的控制范圍,主要是兩個(gè)事務(wù)之間的相互影響關(guān)系。

傳播級(jí)別:

1)、REQUIRED

如果當(dāng)前方法已經(jīng)在事務(wù)中,那么就以父事務(wù)執(zhí)行,不需要新建事務(wù);如果當(dāng)前方法不在事務(wù)中,那么就為當(dāng)前方法新建事務(wù)?;貪L情況:父子方法中任何地方出現(xiàn)問(wèn)題,都會(huì)全部回滾。

2)、SURPPORTED

如果當(dāng)前方法已經(jīng)在事務(wù)中,那么就以當(dāng)前事務(wù)執(zhí)行;如果當(dāng)前方法不再事務(wù)中,那么就以非事務(wù)方式運(yùn)行。如果運(yùn)行在事務(wù)中,那么只要出現(xiàn)異常都會(huì)回滾。

3)、NOT_SURPPORTED

如果當(dāng)前方法已經(jīng)在事務(wù)中,那么就掛起當(dāng)前事務(wù),以非事務(wù)方式運(yùn)行,方法執(zhí)行完畢后,恢復(fù)事務(wù);如果當(dāng)前方法不再事務(wù)中,那么就以非事務(wù)方式執(zhí)行。

4)、MANDATORY

強(qiáng)制以事務(wù)方式執(zhí)行,如果當(dāng)前方法不在事務(wù)中,那么會(huì)拋出異常。

5)、NEVER

與MANDATORY相反,強(qiáng)制以非事務(wù)方式執(zhí)行,如果當(dāng)前方法在事務(wù)中,那么會(huì)拋出異常。

6)、REQUIRED_NEW

與REQUIRED不同的是,無(wú)論該方法當(dāng)前是不是在事務(wù)中,都會(huì)為自己新建一個(gè)事務(wù)。如果當(dāng)前已經(jīng)在事務(wù)中,那么會(huì)掛起父事務(wù),為自己新建一個(gè)事務(wù)。父事務(wù)不影響它子事務(wù)的提交和回滾。

7)、NESTED

嵌套事務(wù)。理解Nested的關(guān)鍵是savepoint。他與PROPAGATION_REQUIRES_NEW的區(qū)別是,PROPAGATION_REQUIRES_NEW另起一個(gè)事務(wù),將會(huì)與他的父事務(wù)相互獨(dú)立,而Nested的事務(wù)和他的父事務(wù)是相依的,他的提交是要等和他的父事務(wù)一塊提交的。也就是說(shuō),如果父事務(wù)最后回滾,他也要回滾的。而Nested事務(wù)的好處是他有一個(gè)savepoint。

例如:

ServiceA {

/**

* 事務(wù)屬性配置為 PROPAGATION_REQUIRED

*/

void methodA() {

try {

//savepoint

ServiceB.methodB(); //PROPAGATION_NESTED 級(jí)別

} catch (SomeException) {

// 執(zhí)行其他業(yè)務(wù), 如 ServiceC.methodC();

}

}

}

也就是說(shuō)ServiceB.methodB失敗回滾,那么ServiceA.methodA也會(huì)回滾到savepoint點(diǎn)上,ServiceA.methodA可以選擇另外一個(gè)分支,比如ServiceC.methodC,繼續(xù)執(zhí)行,來(lái)嘗試完成自己的事務(wù)。

原文鏈接:https://blog.csdn.net/wgh1015398431/java/article/details/52861048

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容