2017-06-19 72 views
1

REQUIRES_NEW被回滾所有交易:Grails的/春REQUIRES_NEW回滾外部事務

我有一個方法,一個bean也有一些方法標記@Transactional(propagation = REQUIRED)內標@Transactional(propagation = REQUIRES_NEW) 。這些方法從不互相呼叫。它們是從另一個bean單獨調用的。但是,如果我的方法被標記爲REQUIRES_NEW失敗,它會回滾整個事務,包括標記爲REQUIRED(這是有問題的)的方法。

我的理解是,如果以這種方式考慮,Spring AOP將有機會攔截REQUIRES_NEW方法並啓動新的邏輯事務。

總的想法是這樣的:

@Transactional 
class TransactionalBean{ 

    @Transactional(propagation = REQUIRED) 
    public void methodA(){ //do transactional work } 

    @Transactional(propagation = REQUIRES_NEW) 
    public void methodB(){ //do transactional work } 
} 

然後調用豆看起來像這樣:

@Transactional 
class CallingBean{ 
    @Autowired 
    TransactionalBean 

    public void doWork(){ 
     TransactionalBean.methodA(); 
     TransactionalBean.methodB(); 
    } 
} 

所以,如果方法A和B成功,一切都很好。但是,當方法B失敗時,方法A中的工作會回滾。我的理解是,當methodB()被調用,它'應該'被AOP截獲並開始一個新的事務並掛起另一個事務,但它不起作用。我該如何解決?我正在使用Grails 2.5,休眠,JPA

+0

最好的辦法來解決它是升級。 2.5不再維護。 –

+0

不幸的是,我被困在這個項目的2.5上。這是框架問題嗎? – dirtbiker

回答

0

問題在於CallingBean標記爲@Transactional的方式。發生什麼事是CallingBean正在創建一個交易,比如說t1CallingBean正在調用兩個事務方法methodA和methodB。由於methodA需要交易,因此它將利用現有的交易t1。然而,methodB將創建一個新的交易,因爲註釋需要一個新的交易,比如t2。當控件退出方法A時,方法A的事務邊界不會結束,而是一直保持活動狀態,直到方法B從調用bean開始的事務完成爲止。既然事務t2在methodB中失敗了,異常會冒泡到調用bean並且事務t1將失敗。

爲了解決這個問題,您可以根據您的需要執行以下操作之一。

關閉CallingBean類中的@Transactional註釋。

//@Transactional 
class CallingBean{ 
... 
} 

更新註釋使用noRollbackFor選項

@Transactional(noRollbackFor={WhateverException.class}) 
class CallingBean{ 
... 
}