2012-02-23 41 views
1

我使用Spring 3.0.5,Hibernate 3.6.7和Atomikos Transactionessentials 3.7.0。使用applicationContext.xml中的AOP配置的事務。 一切工作正常。 (commit,rollback)如何捕捉JTA事務內部拋出的異常?

我的意圖是在jta事務中拋出一個特定的異常。 這種方式應該回滾事務,並獲得有關回滾原因的詳細信息。

問題是,我唯一可以接受的例外是atomikos拋出的回滾事務,告訴我,事務意外回滾。

如何在事務之外獲得自己的異常?

這是一個小例子,因爲我不知道我的解釋是否足夠好。 這只是爲了證明我的意圖。請不要評論任何錯別字。

特定異常(可能有一些標準的異常以及):

public class MySpecialException extends Exception { 
    public MySpecialException(String someInfo) { 
     super(someInfo); 
    } 
} 

接口declareing其中聲明拋出異常的方法:

public interface MyInterface { 
    Object someJtaTransactionMethod(String param) throws MySpecialException; 
} 

類實現該接口:

public class MyClass implements MyInterface { 
    Object someJtaTransactionMethod(String param) throws MySpecialException { 

     // some operations with some errorstate detected 
     // so throw the exception: 
     throw new MySpecialException("Things went terribly wrong!"); 

     // some other code 
    } 
} 

而一些調用函數並捕獲e xceptions。

public class Caller { 

    @Autowired 
    private MyInterface callee; 

    public void test() { 
     try { 
      callee.someJtaTransactionMethod("Some test"); 
     } catch (MySpecialException mex) { 
      // I want to get here 
     } catch (Exception ex) { 
      // but I only get here 
     } 
    } 
} 

這可能嗎?

更新:當然,我看看異常的原因。異常本身是org.springframework.transaction.UnexpectedRollbackException。原因是類javax.transaction.RollbackTransaction並導致com.atomikos.icatch.RollbackException。我認爲會發生什麼是,atomikos注意到異常並執行回滾(根據需要),但atomikos(也許其他jta實現)引發異常,指示事務回滾(意外)和我的例外消失了。

更新2:有趣的是,如果我沒有做過任何必須回滾的事情,我可以根據需要捕捉我的異常!

更新3和解決方案:JB Nizet指出我的解決方案。事實上,我的交易沒有被懷疑回滾,但由於我拋出異常的原因,我得到了違反規定的情況,因此atomikos在提交時拋出了異常。現在,我配置了我的事務來回滾我的異常,一切都按預期和期望工作。

+0

我不知道Atomikos,但它可能是因爲他們捕捉到了你的異常,並將自己與自己的異想天開拋在了一起?你分析了異常的getCause()方法的返回值(從你的第二次捕獲)? – 2012-02-23 21:24:37

+0

是的,我仔細看了一下例外情況(在開發過程中不止一次),並且試圖調試它,但是我找不到任何東西......更新後的文章 – AlexS 2012-02-23 21:31:57

+0

您能否提供堆棧跟蹤和版本的你正在使用的框架? – 2012-02-23 21:35:11

回答

3

你的異常是運行時異常還是檢查異常?

默認情況下,如果拋出運行時異常,則默認彈出回滾,如果拋出檢查的異常,則默認提交。

從堆棧跟蹤看來,你的異常是一個檢查異常,所以Spring試圖提交,但不能,因爲JTA TM(Atomikos)拒絕提交(例如由於超時)。

因此,如果您希望此異常導致回滾,請將其設置爲運行時異常或將其聲明在@Transactional批註的rollbackFor屬性中。如果它不能導致回滾,那麼試着發現爲什麼Atomikos拒絕提交(太短的超時,別的東西......日誌可以幫助)。

+0

一些有趣的信息。通常如果我有這樣的異常,我調試成atomikos並找到真正的原因(例如一些hibernate或jdbc異常)。明天早上我會繼續檢查這個問題.....不能讓我的眼睛再次開放。 – AlexS 2012-02-23 22:53:56

+0

非常感謝。你拯救了我的一天。我只是將我的異常更改爲從RuntimeException繼承,現在一切正常。我之前沒有注意到,當我拋出我自己的異常時,atomikos沒有回滾,並且由於拋出異常,我不知何故昨天無法調試到atomikos。 – AlexS 2012-02-24 07:15:39

0

看起來像一個類型給我,因爲你拋出一個MySpecialException異常繼承而不是MyException?

否則捕獲MySpecialException而不是MyException。

+0

我已經說過這只是一個例子,錯別字不是問題。我真正的代碼編譯和definitly試圖捕捉正確的異常(否則編譯器會告訴我...)糾正它... – AlexS 2012-02-23 21:04:29