2010-11-13 14 views
23

Um die Funktionsweise von Spring-Transaktionen zu verstehen, möchte ich wissen, was im folgenden Fall passiert, wo eine als @Transactional markierte Methode eine andere Methode aufruft, die als @Transactional markiert ist.Spring-Transaktionen verstehen - Was passiert, wenn eine Transaktions-Methode eine andere Transaktions-Methode aufruft?

Angenommen, die Konfiguration verwendet alle Standardeinstellungen.

@Service("myService") 
@Transactional 
public MyService{ 
    public void myServiceMethod(){ 
     myDAO.getSomeDBObjects(); 
    } 
} 

@Repository("myDAO") 
@Transactional 
public MyDAOWithUsesBeyondMyService{ 
    public void getSomeDBObjects(){...} 
} 

Nun, wenn ich MyService.myServiceMethod() eingeben wäre, würde es eindeutig eine Transaktion starten. Dann, nach dem Bohren in myDAO.getSomeDBObjects() was würde passieren? Würde die Tatsache, dass eine Transaktion bereits existiert, keine neue Transaktion hervorbringen, oder erstelle ich hier zwei Transaktionen?

Die Dokumentation (unten zitiert) auf Propagation scheint dies zu decken, aber ich möchte mein Verständnis verifizieren, es war ein bisschen viel für mein jungfräuliches Gehirn, alles auf einmal zu verstehen.

Vermehrung: In der Regel alle Code innerhalb eines Transaktionsbereichs ausgeführt wird in dieser Transaktion ausführen. Sie haben jedoch die Möglichkeit, das Verhalten für den Fall anzugeben, dass eine Transaktionsart ausgeführt wird, wenn bereits ein Transaktionskontext existiert. Zum Beispiel kann Code weiterhin in der bestehenden Transaktion ausgeführt werden ( häufigsten Fall); oder die bestehende Transaktion kann ausgesetzt werden und eine neue Transaktion erstellt werden. Spring bietet alle der Transaktionsausbreitungsoptionen , die von EJB CMT bekannt sind. Um über die Semantik der Transaktion Propagierung im Frühling zu lesen, siehe Abschnitt 10.5.7, "Transaction Propagation".

Antwort

33

Zwei Antworten:

a) tun es nicht. Verwenden Sie @Transactional in der Service-Schicht oder der Dao-Schicht, aber nicht beide (die Service-Schicht ist die übliche Wahl, wie Sie wahrscheinlich eine Transaktion pro Service-Methode wollen)

b) Wenn Sie es tun, was passiert, hängt von der propagation Attribut der @Transactional Annotation und wird in diesem Abschnitt beschrieben: 10.5.7 Transaction propagation. Grundsätzlich gilt: PROPAGATION_REQUIRED bedeutet, dass die gleiche Transaktion für beide Methoden verwendet wird, während PROPAGATION_REQUIRES_NEW eine neue Transaktion startet.

Über Ihre Kommentare:

Natürlich las ich weiter und erkannte, dass, wie ich bin mit Proxies, dieses zweite Verfahren nicht durch die Transaktions Proxy verwaltet werden, so ist es wie jedes andere Methodenaufruf.

Das trifft in Ihrer Situation nicht zu (nur wenn beide Methoden in derselben Klasse waren).

Wenn ein Bean-Methoden hat a und b und a Anrufe b, dann wird b auf der tatsächlichen Methode aufgerufen, nicht die Vollmacht, weil sie aus dem Proxy aufgerufen wird (eine Bohne weiß nicht, dass es proxied ist zur Außenwelt).

proxy  bean 
a() --> a() 
      | 
      V 
b() --> b() 

In Ihrer Situation würde jedoch ein Dienst ein injizierten dao-Objekt, das ein Proxy selbst wäre, so würden Sie eine Situation wie diese haben:

  proxy  bean 
service a() --> a() 
         | 
      /---------/ 
      |     
      V 
dao  b() --> b() 
+0

Danke, ja, ich Ich beabsichtige nicht, dies zu tun, aber die Frage kam mir in den Sinn, als ich feststellte, dass ich @Transactional auf Dienstklassenebene deklariert hatte, und eine Methode des Dienstes eine andere Methode des Dienstes aufruft (beide transaktional). Natürlich las ich weiter und merkte, dass diese zweite Methode, da ich Proxies verwende, nicht vom Transaktions-Proxy verwaltet wird, also wie jeder andere Methodenaufruf (das reicht aus, um ein neu initiiertes Gehirn zu verwirren). :) Aber es hat mich neugierig genug gemacht, um sicherzustellen, dass ich die Details verstanden habe, wie alles funktioniert, das hast du für mich klargestellt. Vielen Dank! –

+0

@David Ich denke, Sie haben das Proxy-Konzept ein wenig missverstanden. Lies mein Update. –

+0

Sie sind absolut richtig, mein Kommentar war falsch (eigentlich habe ich Annahmen gewechselt, ohne es zu sagen), aber ich verstehe, was Sie sagen, und nach all dem denke ich, dass die ganze Sache nun in meinem Kopf verankert ist. Danke für das Update und die tollen Diagramme, ich bin mir sicher, dass viele andere es für ihre zukünftigen Suchen nützlich finden werden! –

Verwandte Themen