Spring 事務(wù)傳播行為和隔離級別的應(yīng)用

一言蔽之

對Spring事務(wù)了解一直處于理論階段,幾個事務(wù)傳播行為(propagation behaviors),幾個隔離級別(isolation levels)看了又忘,忘了又看。近期的開發(fā)中遇到了幾個有趣的例子,拿出來曬曬。

具體應(yīng)用

1. 在catch塊中,繼續(xù)進(jìn)行數(shù)據(jù)庫操作

場景

以下是簡化后的Kotlin代碼
execute()在事務(wù)內(nèi)執(zhí)行
doSomeThing()可能會拋出RuntimeException
fail() 會對數(shù)據(jù)庫有一些修改操作


@Transactional
override fun execute() {
    try {
        doSomeThing()
    } catch (e: Exception) {
        fail()
    }
}

override fun fail() {
   saveLogToDB()
}

問題
如果doSomeThing()拋出RuntimeException,fail()在執(zhí)行數(shù)據(jù)庫操作時,會拋出異常:
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

分析&思路

  1. 方法saveLogToDB()執(zhí)行時事務(wù)已經(jīng)被標(biāo)記為rollback-only
  2. saveLogToDB()使用的事務(wù)是在execute()方法執(zhí)行之前創(chuàng)建的
  3. doSomeThing()執(zhí)行的某個步驟中,因為觸發(fā)異常,事務(wù)被標(biāo)記為rollback-only
  4. 那么,為了saveLogToDB()能夠保存數(shù)據(jù)到數(shù)據(jù)庫,就不能夠使用execute()方法的事務(wù)了。

回憶以下有哪些事務(wù)的傳播行為:

// 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則創(chuàng)建一個新的事務(wù)。
    // @Transactional 注解默認(rèn)采用這個方案
    REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

    // 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則以非事務(wù)的方式繼續(xù)運行。
    SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

    // 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則拋出異常。
    MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

     // 創(chuàng)建一個新的事務(wù),如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
    REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

    // 以非事務(wù)方式運行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
    NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

    // 以非事務(wù)方式運行,如果當(dāng)前存在事務(wù),則拋出異常。
    NEVER(TransactionDefinition.PROPAGATION_NEVER),

    // 如果當(dāng)前存在事務(wù),則創(chuàng)建一個事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來運行;如果當(dāng)前沒有事務(wù),則該取值等價于REQUIRED
    // 并非所有的TransactionManager都能支持這個傳播級別
    NESTED(TransactionDefinition.PROPAGATION_NESTED);

作者:whthomas
鏈接:http://www.itdecent.cn/p/e56b440e9eb6
來源:簡書
簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。

顯然,這里需要使用REQUIRES_NEW傳播行為。

解決
fail()方法上加上事務(wù),并讓propagation = REQUIRES_NEW

@Transactional(propagation = Propagation.REQUIRES_NEW)
override fun fail() {
   saveLogToDB()
}

注意:同一個類中,方法間調(diào)用,事務(wù)AOP生效的前提條件是使用CGLIB方式實現(xiàn)AOP。

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

相關(guān)閱讀更多精彩內(nèi)容

  • 事務(wù),是為了保障邏輯處理的原子性、一致性、隔離性、永久性。 通過事務(wù)控制,可以避免因為邏輯處理失敗而導(dǎo)致產(chǎn)生臟數(shù)據(jù)...
    uzip柚子皮閱讀 4,808評論 3 16
  • 事務(wù)的嵌套概念 所謂事務(wù)的嵌套就是兩個事務(wù)方法之間相互調(diào)用。spring事務(wù)開啟 ,或者是基于接口的或者是基于類的...
    jackcooper閱讀 1,499評論 0 10
  • 很多人喜歡這篇文章,特此同步過來 由淺入深談?wù)搒pring事務(wù) 前言 這篇其實也要歸納到《常識》系列中,但這重點又...
    碼農(nóng)戲碼閱讀 4,904評論 2 59
  • 從前有一個老人,他有三個兒子。 有一天,三個兒子開始比絕招,大兒子出了一個謎題,樹上七只猴,地下一只猴,一共有幾只...
    猴一棒閱讀 249評論 0 2
  • 了解了窮文富武的概念。 高考的公平在于比起大城市的優(yōu)良素質(zhì)教育,給廣大農(nóng)村及不富裕的地區(qū)的孩子一個只要肯下功夫把書...
    cuijieshi閱讀 318評論 0 0

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