使用Spring管理事務過程中,碰到過一些坑,因此也稍微總結一下,方便后續(xù)查閱。 1.代碼中事務控制的3種方式
2.事務不回滾的原因 在工作中,看過別人寫的代碼出現了事務不回滾的現象。當然,事務不回滾的都是采用的聲明式事務或者是注解事務;編程式事務都是自己寫代碼手動回滾的,因此是不會出現不回滾的現象。 再說下聲明式事務和注解事務回滾的原理:當被切面切中或者是加了注解的方法中拋出了RuntimeException異常時,Spring會進行事務回滾。默認情況下是捕獲到方法的RuntimeException異常,也就是說拋出只要屬于運行時的異常(即RuntimeException及其子類)都能回滾;但當拋出一個不屬于運行時異常時,事務是不會回滾的。 下面說說我經常見到的3種事務不回滾的產生原因:
3.如何保證事務回滾 正常情況下,按照正確的編碼是不會出現事務回滾失敗的。下面說幾點保證事務能回滾的方法
① 聲明式事務,在配置里面添加一個rollback-for,代碼如下 1 1 <tx:method name='update*' propagation='REQUIRED' rollback-for='java.lang.Exception'/> ② 注解事務,直接在注解上面指定,代碼如下 @Transactional(rollbackFor=Exception.class) 1 1 @Transactional(rollbackFor=Exception.class)
/** TransactionAspectSupport手動回滾事務:*/ @Transactional(rollbackFor = { Exception.class }) public boolean test() { try { doDbSomeThing(); } catch (Exception e) { e.printStackTrace(); //就是這一句了, 加上之后拋了異常就能回滾(有這句代碼就不需要再手動拋出運行時異常了) TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return false; } return true; } 1 /** TransactionAspectSupport手動回滾事務:*/ 2 @Transactional(rollbackFor = { Exception.class }) 3 public boolean test() { 4 try { 5 doDbSomeThing(); 6 } catch (Exception e) { 7 e.printStackTrace(); 8 //就是這一句了, 加上之后拋了異常就能回滾(有這句代碼就不需要再手動拋出運行時異常了) 9 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 10 return false; 11 } 12 return true; 13 } |
|