spring的事務提交與回滾機制
阿新 • • 發佈:2019-01-26
事務超時:@Transactional(timeout = 60)如果用這個註解描述一個方法的話,執行緒已經跑到方法裡面,如果已經過去60秒了還沒跑完這個方法並且執行緒在這個方法中的後面還有涉及到對資料庫的增刪改查操作時會報事務超時錯誤(會回滾)。如果已經過去60秒了還沒跑完但是後面已經沒有涉及到對資料庫的增刪改查操作,那麼這時不會報事務超時錯誤(不會回滾)。回滾:注意:如果事務在try{ }catch(Exception e){ e.printStackTrace();}中跑,並且catch中只是列印e的話,那麼事務不會rollback。因為異常被catch掉了,框架不知道發生了異常。如果想要rollback,可以加上rollbackFor=Exception.class,然後:①在方法上新增 throws Exception,將方法中出現的異常丟擲給spring事務,②去掉方法體中的try catch③catch (Exception e) { throw e;}繼續向上拋,目的是讓spring事務捕獲這個異常。④不加rollbackFor=Exception.class,catch(){ throw new RunTimeException();}如果不加rollbackFor=Exception.class,丟擲new Exception() 是不會回滾的。Spring原始碼如下:
public boolean rollbackOn(Throwable ex) { return (ex instanceof RuntimeException || ex instanceof Error);} 如果是RuntimeException或Error的話,就返回True,表示要回滾,否則返回False,表示不回滾。
只有spring事務捕獲到Exception異常後,@Transactional(rollbackFor=Exception.class), 才會起到應有的作用;catch (Exception e) { e.printStackTrace(); }這句是捕獲try中出現的Exception然後將異常資訊打印出來,僅僅是打印出來,然後什麼也沒幹。@Transactional(timeout = 60,rollbackFor=Exception.class)與@Transactional(timeout = 60)區別:rollbackFor=Exception.class的作用是讓checked例外也回滾,即讓編譯錯誤也回滾。需要註明的是:1 讓checked例外也回滾:在整個方法前加上 @Transactional(rollbackFor=Exception.class)
2 讓unchecked例外不回滾: @Transactional(notRollbackFor=RunTimeException.class)
checked exception 是編譯時的錯誤,Unchecked exception是執行時錯誤,詳見http://meng702.iteye.com/blog/998379轉載:http://blog.csdn.net/heweimingming/article/details/51841133
public boolean rollbackOn(Throwable ex) { return (ex instanceof RuntimeException || ex instanceof Error);} 如果是RuntimeException或Error的話,就返回True,表示要回滾,否則返回False,表示不回滾。
只有spring事務捕獲到Exception異常後,@Transactional(rollbackFor=Exception.class),
2 讓unchecked例外不回滾: @Transactional(notRollbackFor=RunTimeException.class)
checked exception
附:
今天做一個插入操作時發現事務不起作用,嘗試了各種辦法都沒有奏效,結果發現是mysql資料庫使用的引擎型別是MYISAM,這種引擎是不支援事務的,於是更換為innodb。
另外想說的是,在springmvc的service層處理事務時,可以在service使用try..catch..,catch中主動丟擲.執行時異常,方法上寫@Transactional即可,異常拋給controller處理。另外一種辦法,service不catch,也不用throws,直接就是@Transactional。