ich von Kalpesh Soni
nur mit Antwort stimme ich würde gerne etwas mehr hinzufügen.
Container verwendet den gleichen Thread für die Ausführung von einem zu anderen EJB-Aufrufen. Ein Thread könnte mit nur einer globalen Transaktion verbunden sein, die von TM verwaltet wird. Deshalb @Asynchronous
Bean-Aufruf propagiert keine Transaktion (EJB 3.2 Spezifikation, 4.5.3 Transaktionen). Die Transaktion kann nicht über mehrere Threads aufgeteilt werden und ist an den aufrufenden Thread gebunden.
Wenn Bean als CMT markiert ist, verwaltet der Container die Transaktionskreationen basierend auf der Annotation oder den Informationen aus dem Deskriptor ejb-jar.xml
. Container kann dann entscheiden, ob der Aufruf der Bean-Methode Teil der gerade ausgeführten Transaktion sein oder ob eine neue erstellt werden soll. Wie bereits erwähnt, wird die verschachtelte Transaktion in den meisten Java EE-Containern nicht unterstützt. Nach meinem Verständnis ist der Hauptgrund, dass XAResource verschachtelte Transaktionen nicht unterstützt (siehe JTA spec).
Die BMT-Bean verwendet UserTransaction
, um das Transaktionsmanagement eigenständig zu steuern. Wie sollte eine bestehende Transaktion zur BMT funktionieren oder besser, was könnte man damit machen? Wenn Sie eine neue Transaktion mit UserTransaction.begin()
starten möchten, wird die aktuell laufende gesperrt. So funktioniert nun die Propagierung. Ich meine, die Transaktion wird nicht verbreitet, sondern beim BMT-Bean-Aufruf ausgesetzt. Die andere Sache, die Sie tun könnten, ist die Transaktion zu fahren. Es bedeutet, UserTransaction.commit()
oder UserTransaction.rollback()
bei eingehenden Transaktion verwenden. Wenn Sie dies tun, würde der Aufrufer bei der Rückkehr ohne aktive Transaktion in seinem Kontext arbeiten.Das bedeutet, dass ein Aufruf einer anderen Bean mit Ihrer Transaktion funktionieren könnte, ohne dass Sie als Anrufer darüber informiert werden. Ich denke, dass du das nicht möglich sein willst. Das ist mein Verständnis über die Gründe dahinter.
Es gibt noch eine andere lustige Sache über BMT. Wenn Sie ein SLSB (Stateless Session Bean) verwenden, dürfen Sie die aufgerufene Methode nicht beenden, ohne die Transaktion abzuschließen (siehe EJB 3.2: 8.3.3 Enterprise Beans Using Bean-Managed Transaction Demarcation). Auf der anderen Seite kann SFSB (Stateful Session Bean) eine Methode beenden, ohne die Transaktion zu beenden, und die in einem anderen Aufruf beendet werden könnte. Wenn ein solcher Anruf z.B. in einer anderen HTTP-Sitzung wird die Transaktion ausgesetzt und aus dem aktuellen Thread übernommen und später aktiviert und an neuen Thread angeheftet.
javax/Transaktion/a/XAResource.html "XAResource Java EE 7 API"
An Gebildete Vermutung: Ein Grund könnte sein, Ressourcenverluste im Container zu vermeiden. Es ist eine gute Faustregel, dass eine Klasse, die eine Ressource erstellt, auch für das Bereinigen einer Ressource zuständig sein sollte. und wenn es passiert, dass es nach dem Beenden nicht sauberräumt, kann der Container alle offenen Ressourcen, die von der EJB geöffnet wurden (z. B. offene Transaktionen), schließen, um einen Ressourcenleck zu vermeiden, was gefährlich wäre. Ein ähnliches Beispiel sind offene Dateideskriptoren von Prozessen in * nix, die beim Beenden des Prozesses vom Kernel geschlossen werden. –