2011-10-26 43 views
3

我使用類似於接縫組件@Transactional註釋:Seam @Transactional註解不起作用?

@Name("myComponent") 
@AutoCreate 
public class MyComponent 
{ 
    public void something() { 
     ... 
     doWork(); 
    } 
    ... 
    @Transactional 
    protected void doWork() { 
     try { 
      log.debug("transaction active: " + Transaction.instance().isActive()); 
     } catch (Exception ignore) {} 

     // some more stuff here that doesn't appear to be inside a transaction 
    } 
} 

在「一些更多的東西」一節中,我修改了一些休眠的實體,然後其中有一個異常被拋出的錯誤。我注意到Exception並沒有導致事務回滾(修改後的實體仍然在數據庫中修改),所以我添加了「transaction active」日誌記錄。當此代碼執行時,isActive()返回false。

有什麼我失蹤了嗎?爲什麼交易不活躍?

萬一它很重要,我從另一個使用RESTEasy註釋的組件內部使用Seam組件來觸發我的方法調用。

回答

6

我不熟悉Seam的工作方式,所以如果這個答案不適用,我會事先道歉。

我注意到@Transactional的方法是protected。這意味着它正在被另一種內部方法調用。

與Spring AOP,你標記公共方法與@Transactional被包裹並與交易代理更換。當外部類調用public方法時,它將調用形成事務的代理。如果外部類別調用另一個public方法而不是標記爲@Transactional然後調用一個內部方法,即不會創建事務,因爲根本沒有調用該代理。

在春天,即使您將doWork()方法更改爲公開,也會發生同樣的問題。沒有事務,因爲代理對象沒有被調用。在類內部進行的方法調用不會調用代理對象。

快速閱讀一些文檔似乎表明,像Spring AOP一樣,Seam使用的是CGLib proxying。問題是它是否能夠代理所有方法 - 即使它們是從代理對象內部調用的。對不起,浪費你的時間,如果這個答案不適用。

+0

可能與http://stackoverflow.com/questions/3401821/weld-injection-failing-when-calling-a-method-from-an-super-abstract-class-with-w – Gray

+0

我認爲你是在這裏的東西 –

+2

接受這個,因爲他真的很接近Seam的問題。除非您從一個Seam組件轉到另一個組件,否則不會使用@Transactional註釋。在這種情況下,我們從相同的Seam組件(MyComponent)中調用了Transactional方法。通過將對Transactional方法的調用拉出到另一個組件,TransactionInterceptor現在被觸發並且一切都很好。 –