2016-11-15 97 views
0

我在非事務性方法中調用try-catch塊內的兩個事務性方法。當發生異常時,我能夠捕獲異常並將其記錄下來。第一個交易方法不會回滾,但最後一個交易方法會回滾。這種行爲是我目前在春季交易管理中所瞭解的。即使在非事務性方法或控制器中捕獲異常,Spring事務性方法也會回滾

public void grab(){ 
    try{ 
     requestManager.updateRequest(); 
     requestManager.saveTicket() 
    }catch (DataIntegrityViolationException dive) { 
     if (dive.getCause() instanceof ConstraintViolationException) { 
      LOGGER.error("ConstraintViolationException",dive); 
     } 
    } 
} 

在上面的代碼中,ConstraintViolationException內saveTicket()方法和內部saveTicket的DAO()已經回滾其事務,甚至捕捉異常之前(這是我知道的)發生,並且第一個廣告沒有回滾,因爲它在另一個事務中(這是我已經知道的行爲)。

當我使用另一個調用這兩個預覽方法的update事件方法(updateRequest()和saveTicket())時,即使在saveTicket()方法中發生ConstraintViolationException異常時也會回滾updateRequest()方法,例外。這裏是我的代碼

public void grab(){ 
    try{ 
     requestManager.grabRequest(); 
    }catch (DataIntegrityViolationException dive) { 
     if (dive.getCause() instanceof ConstraintViolationException) { 
      LOGGER.error("ConstraintViolationException",dive); 
     } 
    } 
} 

我知道的是,這兩種方法將加入同一個事務中grabRequest()方法,但我的問題是什麼,爲什麼交易被回滾即使我捕捉異常?這是否意味着即使在我發現異常之前,Spring使用的代理已經回滾了事務?

+0

?奇怪的是,事務在saveTicket()中回滾並且spring只是重新拋出異常?預期的行爲是什麼?另外我想,你沒有註釋只有'@ Transactional'方法,但整個類,所以這就是爲什麼在第二個例子'grabRequest()'它回滾這兩個事務。你可以發佈'requestManager'類以及3個提到的方法 – AntJavaDev

+0

感謝您的迴應。但爲什麼奇怪的是事務會在saveTicket中回滾?我所知道的是,由於例外,dao不會持續數據。因此,即使我發現異常,saveTicket()中的dao已經回退。是的,grabRequest()也是事務性的,這就是爲什麼它會回滾整個事務。但爲什麼春天將它捲回,即使它被抓到裏面試試看?是因爲春天使用的代理嗎? – xian

+0

您正在捕捉一個異常,在您的事務處理完成後,將在春季被重新拋出。如果你進入'saveTicket()'方法並捕獲異常,則事務顧問程序不會按預期工作。但是我仍然感到困惑,你的實際目標是什麼?春天是否按預期工作有問題嗎? – AntJavaDev

回答

0

這是否意味着,即使在我發現異常之前,spring使用的代理已經回滾了事務?

是的,在JPA /春批註您可以指定例外列表,您的事務管理器必須回滾或@Transactional

在其默認的配置不能回滾,Spring框架的事務架構代碼僅在運行時標記一個用於回滾的事務,未經檢查的異常;也就是說,拋出的異常是RuntimeException的一個實例或子類時。 (錯誤也會 - 默認情況下 - 導致回滾)。從事務性方法引發的檢查異常不會導致默認配置中的回滾。

http://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html

對於JPA是rollbackOndontRollbackOn

+0

非常感謝您的回答! – xian

相關問題