小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

淺談Spring中的事務(wù)回滾

 甘甘灰 2018-08-06
    使用Spring管理事務(wù)過(guò)程中,碰到過(guò)一些坑,因此也稍微總結(jié)一下,方便后續(xù)查閱。

1.代碼中事務(wù)控制的3種方式

    • 編程式事務(wù):就是直接在代碼里手動(dòng)開啟事務(wù),手動(dòng)提交,手動(dòng)回滾。優(yōu)點(diǎn)就是可以靈活控制,缺點(diǎn)就是太麻煩了,太多重復(fù)的代碼了。
    • 聲明式事務(wù):就是使用SpringAop配置事務(wù),這種方式大大的簡(jiǎn)化了編碼。需要注意的是切入點(diǎn)表達(dá)式一定要寫正確。
    • 注解事務(wù):直接在Service層的方法上面加上@Transactional注解,個(gè)人比較喜歡用這種方式。

2.事務(wù)不回滾的原因

    在工作中,看過(guò)別人寫的代碼出現(xiàn)了事務(wù)不回滾的現(xiàn)象。當(dāng)然,事務(wù)不回滾的都是采用的聲明式事務(wù)或者是注解事務(wù);編程式事務(wù)都是自己寫代碼手動(dòng)回滾的,因此是不會(huì)出現(xiàn)不回滾的現(xiàn)象。

    再說(shuō)下聲明式事務(wù)和注解事務(wù)回滾的原理:當(dāng)被切面切中或者是加了注解的方法中拋出了RuntimeException異常時(shí),Spring會(huì)進(jìn)行事務(wù)回滾。默認(rèn)情況下是捕獲到方法的RuntimeException異常,也就是說(shuō)拋出只要屬于運(yùn)行時(shí)的異常(即RuntimeException及其子類)都能回滾;但當(dāng)拋出一個(gè)不屬于運(yùn)行時(shí)異常時(shí),事務(wù)是不會(huì)回滾的。

    下面說(shuō)說(shuō)我經(jīng)常見(jiàn)到的3種事務(wù)不回滾的產(chǎn)生原因:
    • (1)聲明式事務(wù)配置切入點(diǎn)表達(dá)式寫錯(cuò)了,沒(méi)切中Service中的方法
    • (2)Service方法中,把異常給try catch了,但catch里面只是打印了異常信息,沒(méi)有手動(dòng)拋出RuntimeException異常
    • (3)Service方法中,拋出的異常不屬于運(yùn)行時(shí)異常(如IO異常),因?yàn)镾pring默認(rèn)情況下是捕獲到運(yùn)行時(shí)異常就回滾

3.如何保證事務(wù)回滾

    正常情況下,按照正確的編碼是不會(huì)出現(xiàn)事務(wù)回滾失敗的。下面說(shuō)幾點(diǎn)保證事務(wù)能回滾的方法
    • (1)如果采用編程式事務(wù),一定要確保切入點(diǎn)表達(dá)式書寫正確
    • (2)如果Service層會(huì)拋出不屬于運(yùn)行時(shí)異常也要能回滾,那么可以將Spring默認(rèn)的回滾時(shí)的異常修改為Exception,這樣就可以保證碰到什么異常都可以回滾。具體的設(shè)置方式也說(shuō)下:
                        ① 聲明式事務(wù),在配置里面添加一個(gè)rollback-for,代碼如下
1
1
 <tx:method name='update*' propagation='REQUIRED' rollback-for='java.lang.Exception'/> 
                        ② 注解事務(wù),直接在注解上面指定,代碼如下
@Transactional(rollbackFor=Exception.class)
1
1
@Transactional(rollbackFor=Exception.class)
    • (3)只有非只讀事務(wù)才能回滾的,只讀事務(wù)是不會(huì)回滾的
    • (4)如果在Service層用了try catch,在catch里面再拋出一個(gè) RuntimeException異常,這樣出了異常才會(huì)回滾
    • (5)如果你不喜歡(4)的方式,你還可以直接在catch后面寫一句回滾代碼(TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); )來(lái)實(shí)現(xiàn)回滾,這樣的話,就可以在拋異常后也能return 返回值;比較適合需要拿到Service層的返回值的場(chǎng)景。具體的用法可以參見(jiàn)考下面的偽代碼
/** TransactionAspectSupport手動(dòng)回滾事務(wù):*/ @Transactional(rollbackFor = { Exception.class }) public boolean test() { try { doDbSomeThing(); } catch (Exception e) { e.printStackTrace(); //就是這一句了, 加上之后拋了異常就能回滾(有這句代碼就不需要再手動(dòng)拋出運(yùn)行時(shí)異常了) TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return false; } return true; }
1
/** TransactionAspectSupport手動(dòng)回滾事務(wù):*/
2
      @Transactional(rollbackFor = { Exception.class })  
3
       public boolean test() {  
4
           try {  
5
               doDbSomeThing();    
6
          } catch (Exception e) {  
7
                 e.printStackTrace();     
8
                //就是這一句了, 加上之后拋了異常就能回滾(有這句代碼就不需要再手動(dòng)拋出運(yùn)行時(shí)異常了)
9
                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();  
10
                return false;
11
            }  
12
          return true;
13
      }  

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多