Spring學(xué)習(xí)JdbcTemplate數(shù)據(jù)庫(kù)事務(wù)參數(shù)
Spring JdbcTemplate數(shù)據(jù)庫(kù)事務(wù)參數(shù)
@Transactional() 注解里有不少參數(shù),其中我們常用到的如下:

一、propagation
表示事務(wù)傳播行為。就是說(shuō)多個(gè)事務(wù)方法之間進(jìn)行調(diào)用,這個(gè)過(guò)程中事務(wù)是如何進(jìn)行管理的。
這里的事務(wù)方法就是指對(duì)數(shù)據(jù)庫(kù)表數(shù)據(jù)進(jìn)行變化操作的方法。
舉例:
有個(gè) update() 方法:
public void update() {
}還有個(gè) add() 方法:
public void add() {
// 調(diào)用了update()方法
update()
}那么,現(xiàn)在當(dāng)其中一個(gè)方法加上了事務(wù)注解 @Transactional 后,調(diào)用執(zhí)行過(guò)程是怎樣的?或者說(shuō)兩個(gè)都加了事務(wù)注解,又該如何?
為了解決問(wèn)題,spring 事務(wù)傳播行為有 7 種:
- REQUIRED:默認(rèn)參數(shù)。如果有事務(wù)在運(yùn)行,當(dāng)前方法就在這個(gè)事務(wù)內(nèi)運(yùn)行,否則就開啟一個(gè)新的事務(wù),并在自己的事務(wù)內(nèi)運(yùn)行。
- REQUIRES_NEW:當(dāng)前的方法必須在啟動(dòng)新事務(wù),并在它自己的事務(wù)內(nèi)運(yùn)行,如果有事務(wù)在進(jìn)行,應(yīng)該將它掛起。
- SUPPORTS:如果有事務(wù)在運(yùn)行,當(dāng)前的方法就在這個(gè)事務(wù)內(nèi)運(yùn)行,否則它可以不運(yùn)行在事務(wù)中。
- NOT_SUPPORTED:當(dāng)前的方法不應(yīng)該運(yùn)行在事務(wù)中,如果有運(yùn)行的事務(wù),將它掛起。
- MANDATORY:當(dāng)前的方法必須運(yùn)行在事務(wù)內(nèi)部,如果沒有正在運(yùn)行的事務(wù),就拋出異常。
- NEVER:當(dāng)前的方法不應(yīng)該在事務(wù)中運(yùn)行,如果有運(yùn)行的事務(wù),就拋出異常。
- NESTED:如果有事務(wù)在運(yùn)行,當(dāng)前的方法就應(yīng)該在這個(gè)事務(wù)的嵌套事務(wù)內(nèi)運(yùn)行,否則,就啟動(dòng)一個(gè)新的事務(wù),并在自己的事務(wù)內(nèi)運(yùn)行。
1. REQUIRED
如果有事務(wù)在運(yùn)行,當(dāng)前方法就在這個(gè)事務(wù)內(nèi)運(yùn)行,否則就開啟一個(gè)新的事務(wù),并在自己的事務(wù)內(nèi)運(yùn)行。

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
methodB();
// do something
}
@Transactional(propagation = Propagation.REQUIRED)
public void methodB() {
// do something
}當(dāng)調(diào)用 methodA 時(shí),因?yàn)楫?dāng)前上下文不存在事務(wù),所以會(huì)開啟一個(gè)新的事務(wù)。當(dāng)執(zhí)行到 methodB 時(shí),發(fā)現(xiàn)當(dāng)前上下文存在事務(wù),因此就加入到當(dāng)前事務(wù)來(lái)執(zhí)行。當(dāng)單獨(dú)調(diào)用 methodB 時(shí),因?yàn)楫?dāng)前上下文不存在事務(wù),所以會(huì)開啟一個(gè)新的事務(wù)。
2. REQUIRES_NEW
當(dāng)前的方法必須在啟動(dòng)新事務(wù),并在它自己的事務(wù)內(nèi)運(yùn)行,如果有事務(wù)在進(jìn)行,應(yīng)該將它掛起。

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
doSomeThingA();
methodB();
doSomeThingB();
// do something else
}
// 事務(wù)屬性為REQUIRES_NEW
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {
// do something
}當(dāng)調(diào)用 methodA 時(shí),開啟了 事務(wù) A。執(zhí)行到 methodB 時(shí),開啟一個(gè)事務(wù)B,此時(shí)事務(wù) A 掛起,當(dāng)事務(wù) B 執(zhí)行完成后,繼續(xù)執(zhí)行事務(wù) A 。
- 這里的事務(wù) A 稱為外層事務(wù)。
- 這里的事務(wù) B 則稱為內(nèi)層事務(wù)。
3. SUPPORTS
如果有事務(wù)在運(yùn)行,當(dāng)前的方法就在這個(gè)事務(wù)內(nèi)運(yùn)行,否則它可以不運(yùn)行在事務(wù)中。
@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
methodB();
// do something
}
// 事務(wù)屬性為SUPPORTS
@Transactional(propagation = Propagation.SUPPORTS)
public void methodB() {
// do something
}當(dāng)調(diào)用 methodA 時(shí),methodB 加入到 methodA 的事務(wù)中,事務(wù)的執(zhí)行。當(dāng)單獨(dú)的調(diào)用 methodB 時(shí),methodB方法是非事務(wù)的執(zhí)行的。
4. NOT_SUPPORTED
當(dāng)前的方法不應(yīng)該運(yùn)行在事務(wù)中,如果有運(yùn)行的事務(wù),將它掛起。

- 當(dāng)調(diào)用 methodA 時(shí),開啟 事務(wù) A。當(dāng)執(zhí)行到 methodB 時(shí),掛起事務(wù)A,以非事務(wù)的方式執(zhí)行 methodB 。
- 當(dāng)單獨(dú)的調(diào)用 methodB 時(shí),methodB方法是非事務(wù)的執(zhí)行的。
5. MANDATORY
當(dāng)前的方法必須運(yùn)行在事務(wù)內(nèi)部,如果沒有正在運(yùn)行的事務(wù),就拋出異常。
@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
methodB();
// do something
}
// 事務(wù)屬性為MANDATORY
@Transactional(propagation = Propagation.MANDATORY)
public void methodB() {
// do something
}當(dāng)調(diào)用 methodA 時(shí),methodB 則加入到 methodA 的事務(wù)中,事務(wù)地執(zhí)行。當(dāng)單獨(dú)調(diào)用 methodB 時(shí),因?yàn)楫?dāng)前沒有一個(gè)活動(dòng)的事務(wù),則會(huì)拋出異常。
6. NEVER
當(dāng)前的方法不應(yīng)該在事務(wù)中運(yùn)行,如果有運(yùn)行的事務(wù),就拋出異常。
7. NESTED
如果有事務(wù)在運(yùn)行,當(dāng)前的方法就應(yīng)該在這個(gè)事務(wù)的嵌套事務(wù)內(nèi)運(yùn)行,否則,就啟動(dòng)一個(gè)新的事務(wù),并在自己的事務(wù)內(nèi)運(yùn)行。

- 當(dāng)單獨(dú)執(zhí)行 methodB ,開啟事務(wù) B,執(zhí)行。
- 當(dāng)執(zhí)行 methodA 時(shí),開啟事務(wù) A,執(zhí)行到 methodB,開啟內(nèi)層事務(wù) B。
注意 當(dāng)執(zhí)行 methodA 時(shí),這里是一個(gè)嵌套事務(wù)。
如果外層事務(wù)失敗,則會(huì)回滾內(nèi)層事務(wù)所做的操作。但是內(nèi)層事務(wù)的失敗不會(huì)引起外層事務(wù)的回滾。
二、ioslation
設(shè)置事務(wù)隔離級(jí)別。
因?yàn)椴煌氖聞?wù)隔離級(jí)別會(huì)引起不同的問(wèn)題,比如:臟讀、不可重復(fù)讀、幻讀。
相關(guān)的內(nèi)容在之前有過(guò)介紹,有興趣的可以自行跳轉(zhuǎn)過(guò)去:
【Mysql】數(shù)據(jù)庫(kù)事務(wù),臟讀、幻讀、不可重復(fù)讀
所以要解決,需要設(shè)置對(duì)應(yīng)的隔離級(jí)別:
- READ_UNCOMMITTED: 讀未提交
- READ_COMMITTED: 讀已提交
- REPEATABLE_READ: 可重復(fù)讀
- SERIALIZABLE: 串行化

三、timeout
設(shè)置超時(shí)時(shí)間。
事務(wù)需要在一定時(shí)間內(nèi)進(jìn)行提交,如果沒提交,就回滾。
默認(rèn)值是 -1 ,表示不超時(shí)。如果設(shè)置時(shí)間,單位是秒(s)。
四、readOnly
設(shè)置是否只讀。
默認(rèn)值 false,表示可以查詢,也可以進(jìn)行添加、修改、刪除操作。
當(dāng)設(shè)置為 true,只可以進(jìn)行查詢操作。
五、rollbackFor
設(shè)置出現(xiàn)哪些異常后就進(jìn)行事務(wù)的回滾。
六、noRollbackFor
設(shè)置出現(xiàn)哪些異常后,不進(jìn)行事務(wù)的回滾。
以上就是Spring學(xué)習(xí)JdbcTemplate數(shù)據(jù)庫(kù)事務(wù)參數(shù)的詳細(xì)內(nèi)容,更多關(guān)于Spring JdbcTemplate數(shù)據(jù)庫(kù)事務(wù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Spring事務(wù)框架之TransactionStatus源碼解析
- Spring事務(wù)控制策略及@Transactional失效問(wèn)題解決避坑
- Spring?AOP實(shí)現(xiàn)聲明式事務(wù)機(jī)制源碼解析
- Spring強(qiáng)大事務(wù)兼容數(shù)據(jù)庫(kù)多種組合解決業(yè)務(wù)需求
- Spring事務(wù)@Transactional注解四種不生效案例場(chǎng)景分析
- Spring框架JdbcTemplate數(shù)據(jù)庫(kù)事務(wù)管理完全注解方式
- Spring事務(wù)框架之TransactionDefinition源碼解析
相關(guān)文章
springboot應(yīng)用中使用過(guò)濾器的過(guò)程詳解
過(guò)濾器通常用于實(shí)現(xiàn)跨切面的功能,例如身份驗(yàn)證、日志記錄、請(qǐng)求和響應(yīng)的修改、性能監(jiān)控等,這篇文章主要介紹了springboot應(yīng)用中使用過(guò)濾器,需要的朋友可以參考下2023-06-06
Java實(shí)現(xiàn)的數(shù)組去重與排序操作詳解
這篇文章主要介紹了Java實(shí)現(xiàn)的數(shù)組去重與排序操作,結(jié)合實(shí)例形式分析了Java針對(duì)數(shù)組去重及排序操作相關(guān)遍歷、排序、判斷等使用技巧與注意事項(xiàng),需要的朋友可以參考下2018-07-07
Spring的BeanFactoryPostProcessor接口示例代碼詳解
這篇文章主要介紹了Spring的BeanFactoryPostProcessor接口,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
利用openoffice+jodconverter-code-3.0-bate4實(shí)現(xiàn)ppt轉(zhuǎn)圖片
這篇文章主要為大家詳細(xì)介紹了利用openoffice+jodconverter-code-3.0-bate4實(shí)現(xiàn)ppt轉(zhuǎn)圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
java實(shí)現(xiàn)zip,gzip,7z,zlib格式的壓縮打包
本文是利用Java原生類和apache的commons實(shí)現(xiàn)zip,gzip,7z,zlib的壓縮打包,如果你要是感興趣可以進(jìn)來(lái)了解一下。2016-10-10

