2017-02-16 3 views
1

Rücksetzfunktion für Rollback hier getan wird, wie erwartet:Grails (2.3) @Transactional nicht

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

Aber hier nicht - das ist wahrscheinlich falsch ist - try/catch sollte nicht das Verhalten beeinflussen:

@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 
    } 
} 

Antwort

1

vielleicht haben Sie den Zweck des try-catch falsch verstanden oder vielleicht sind Sie nur einen wackeligen Moment mit:

@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()) 
    } 
} 

ich hoffe, dass es erklärt, wo Sie falsch gelaufen sind, aber wirklich möchten Sie all dies in einem Service machen und versuchen, Teil in der Steuerung zu fangen -

so tun Sie Transaktion, und wenn etwas schief geht, möchten Sie möglicherweise zusätzliche Ausnahmen aus werfen Der Dienst, den der Versuch in der Steuerung erfassen würde, würde erfassen und zurücksetzen.

I did a sample project years back here hoffe, es hilft

Eitherway jene Experimente der jemand sind und sind nicht wirklich so, wie Sie über das Tun richtige Codierung gehen würde, ich meine, es ist ein ziemlich seltsam ungewöhnliche Art und Weise, die Dinge zu tun, und kurz er ist nur versuchen, eine Runtime-Exception auszulösen, wodurch ein Rollback ausgelöst wird. Ich bleibe bei meinem Vorschlag in der Antwort, dass Sie einen einmaligen Versuch machen wollen, im Controller zu fangen. Dies versucht, sowohl Validierungsfehler des vorliegenden Objekts als auch Fehler innerhalb des Fehlers einer gegebenen Diensttransaktionsarbeit zu erfassen. Something like this aber wahrscheinlich viel mehr Arbeit, um alle spezifischen Probleme zu erfassen und zurück zur ursprünglichen Seite mit den zugrunde liegenden Problemen - auch jetzt Rollback-Transaktion.

+0

Ich habe erwartet, dass der Proxy die Ausnahme trotzdem erkennt. Siehe Test 2 hier: http://devhobbs.blogspot.de/2015/04/grailsgorm-transactions.html (Test 2 Ergebnis: Kein Datensatz geschrieben. Ausnahme rollt zurück.) –

+0

nur um klar zu sein, Sie sind in einem Dienst? '@Transactional (Propagation = Propagation.REQUIRES_NEW) def test1() {' ist in einem Dienst?anstatt Controller, wenn Sie sich das Beispiel anschauen, das Sie '@Transactionalclass BookService {' – Vahid

+0

Ich aktualisiert mein Answe, da mein Kommentar zurück über Ihr Beispiel usw. zu lange sein würde, überprüfen Sie die aktualisierte Antwort – Vahid

2

Standardmäßig umschließt @Transactional die Methode so, dass jede nicht geprüfte Ausnahme (z. B. RuntimeException) dazu führt, dass die Transaktion zurückgesetzt wird.

Wenn Sie die Ausnahme in der Methode abfangen/behandeln, wird die Ausnahme natürlich nicht bis zum transaktionalen Wrapper weitergegeben und die Transaktion wird nicht als Nur-Rollback markiert. Dies scheint das zu sein, was du tust.

Es ist erwähnenswert, dass Sie angeben können, dass der Transaktions-Wrapper Transaktionen zurücksetzen soll, wenn andere Ausnahmen ausgelöst werden (und an den Wrapper weitergegeben werden). Sie können dies mit dem Annotationsparameter rollbackFor tun.

Zum Beispiel

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

die Transaktion führen zurückgerollt werden, wenn eine Throwable an den Wrapper propagiert, auch diejenigen, die überprüft werden (dh., MyException)

Dies sollte sein Verhalten einer beliebigen @Transactional-Methode, unabhängig davon, ob Sie eine neue Transaktion erstellen oder einen vorhandenen Transaktionskontext erben.

Verwandte Themen