2017-02-16 18 views
1

回滾都是在這裏完成的預期:Grails的(2.3)@事務不會回退

@Transactional(propagation = Propagation.REQUIRES_NEW) 
def test1() { 
    def dummy = new Dummy(name: "test1") 
    dummy.save() 
    throw new RuntimeException("test1!") 
} 

但在這裏沒有 - 這可能是錯誤的 - try/catch語句應該不會影響到行爲:

@Transactional(propagation = Propagation.REQUIRES_NEW) 
def test2() { 
    def dummy = new Dummy(name: "test2") 
    dummy.save() 
    try { 
    throw new RuntimeException("test2!") 
    } catch (all) { 
    println all.message 
    } 
} 

回答

1

也許你誤會嘗試捕捉的目的,或者你只是有一個不穩定的時刻:

@Transactional(propagation = Propagation.REQUIRES_NEW) 
def test2() { 
    //you may be doing other stuff here 
    //but now about to do some transaction work 
    //so lets wrap this method around a try catch 
    try { 
    //this is happening 
    def dummy = new Dummy(name: "test2") 
    dummy.save()  
    } catch (Exception all) { // or catch (Throwable all) { 
    // if something went wrong in above save method 
    //should be caught and runtime exception means roll back 
    throw new RuntimeException("test2!" +all?.toString()) 
    } 
} 

我希望它解釋你出錯的地方,但是你真的希望在服務中做所有這些事情,並且在控制器中做試試抓住的部分 -

所以你做事務工作,如果事情出錯了,你可能希望拋出額外的例外控制器中的try catch會捕獲並將其設置回滾的服務。

I did a sample project years back here希望它有助於

eitherway那些都是別人的實驗,是不是真的,你會去這樣做正確的編碼方式,我的意思是做事情的一個相當奇怪的不尋常的方式,並在很短,他只是試圖使其拋出運行時異常,從而觸發回滾。我堅持我的建議,答案是你想在控制器中試一試。它試圖捕獲手頭對象的驗證錯誤以及任何特定服務交易工作失敗的失敗。 Something like this但是可能還有很多工作要捕獲所有特定問題並返回到帶有潛在問題的原始頁面 - 現在也回滾事務。

+0

我一直盼望代理反正承認例外。見測試2瀏覽:http://devhobbs.blogspot.de/2015/04/grailsgorm-transactions.html(測試2的結果:沒有書面記錄異常回滾。) –

+0

只是要清楚,你是在一個服務? '@Transactional(傳播= Propagation.REQUIRES_NEW) DEF TEST1(){'是在服務?而不是控制器,因爲如果你看看你提供的例子'@Transactionalclass BookService {' – Vahid

+0

我更新了我的回答,因爲我的評論回來了關於你的例子等會太長檢查更新的答案 – Vahid

2

默認情況下,@Transactional包裝該方法,以便任何未檢查的異常(即,RuntimeException)都將導致事務回滾。

如果趕上/處理方法中的例外,當然,異常不會傳播到事務包裝和交易將不被標記爲只回滾。這似乎是你在做什麼。

值得指出的是,你可以指示事務包裝應該回滾事務,如果其他拋出異常(並傳播到包裝)。您可以使用rollbackFor註釋參數執行此操作。

例如,

@Transactional(rollbackFor=Throwable.class) 
void doTransactionalWork() throws MyException { ... } 

會導致事務被回滾,如果任何的Throwable向上傳播到包裝紙,甚至那些被檢查(即,MyException

這應該是無論您是創建新事務還是繼承現有事務上下文,都可以使用任何@Transactional方法的行爲。