2013-07-27 2 views
5

Ein Zitat aus dem EJB 3.1 specification:Warum wirken EJB-Beans mit Bean-verwalteten Transaktionen als "Transaktionsbarriere"?

13.6.1 Bean-Managed Transaktionsdemarkation

Der Behälter muss Client Anrufungen zu einer Enterprise-Bean Instanz mit Bean-verwaltete Transaktionsabgrenzung wie folgt verwalten. Wenn ein -Client eine Geschäftsmethode über eine der Client-Ansichten der Enterprise-Bean aufruft, unterbricht der Container alle Transaktionen, die möglicherweise mit der Clientanforderung verknüpft sind ( ).

Auf der anderen Seite, eine Transaktion von einem eigenständigen Client oder einem andere EJB in eine Container-gesteuerten Transaktionen mit Bohne propagiert. Wenn man es aus der CMT-Perspektive betrachtet, haben Bohnen, die CMT verwenden, ein zusätzliches wichtiges Merkmal (Transaktionsfortpflanzung).

Was ist der Grund für diese Einschränkung ("Transaktionsbarriere"), die Bohnen mit BMT auferlegt wird?

Verwandte Fragen:

+0

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. –

Antwort

-1

Wenn Sie BMT verwenden, verwalten Sie die Transaktion. Sie verwenden UserTransaction zum Erstellen und Commit der Transaktion.

Der Punkt hier ist, dass UserTransaction eine Transaktion im aktuellen Thread erstellen und wenn Sie ein anderes EJB aufrufen, wird dieser Aufruf in einem anderen Thread ausgeführt (mit seinem eigenen EJB-Lebenszyklus).

In CMT wird der Container beim Methodenaufruf für die Verarbeitung der Transaktion zwischengeschaltet.

3.1 Usertransaction Interface (Von JTA-Spezifikation)

Die UserTransaction.begin Methode startet eine globale Transaktion und ordnet die Transaktion mit dem anrufenden Thread. Die Transaktion-zu-Thread-Zuordnung wird transparent vom Transaction Manager verwaltet.

Unterstützung für verschachtelte Transaktionen ist nicht erforderlich. Die UserTransaction.begin-Methode löst die NotSupportedException aus, wenn der aufrufende Thread bereits einer Transaktion zugeordnet ist und die Transaktionsmanager-Implementierung keine verschachtelten Transaktionen unterstützt.

3.2.2 Abschluss einer Transaktion

Die Transaction.Commit-Methode schließt die Transaktion derzeit mit dem aufrufenden Thread zugeordnet ist. Nachdem die commit-Methode zurückgegeben wurde, ist der aufrufende Thread keiner Transaktion zugeordnet. Wenn die Commit-Methode aufgerufen wird, wenn der Thread keinem Transaktionskontext zugeordnet ist, löst das TM eine Ausnahme aus.

13.2.5 Container-Managed Abgrenzung (von EJB-Spezifikation)

Immer wenn ein Client eine Methode ruft Unternehmen auf einem Enterprise-Bean Schnittstelle (oder auf dem No-Interface-View oder zu Hause oder Komponente Schnittstelle einer Enterprise-Bean), der Container zwischen der Methode Aufruf. Die Interposition ermöglicht es dem Container, die Transaktionsdemarkation deklarativ über die vom Entwickler festgelegte Transaktion zu steuern.

+0

Wenn ein EJB, der CMT verwendet, ein anderes EJB mit CMT aufruft, hat auch dieses einen eigenen Lebenszyklus. Warum funktioniert es in diesem Fall? Wie für "dieser Anruf wird in einem anderen Thread ausgeführt werden": Könnten Sie auf den relevanten Abschnitt in der Spezifikation hinweisen, wo dies definiert ist? Mit anderen Worten, ist es wirklich ein anderer Thread? Wenn ein EJB einen anderen EJB anruft, gibt es keinen anderen Thread AFAIK. – Beryllium

+0

Ich habe meine Antwort mit einer ausführlicheren Antwort aktualisiert. Lassen Sie mich jetzt, was denkst du über diese Antwort –

+0

Ich habe auch ein Problem mit dieser Behauptung "wenn Sie ein anderes EJB anrufen, wird dieser Aufruf in einem anderen Thread ausgeführt werden" - ich glaube nicht, dass dies eine Voraussetzung ist –

2

Mein „erraten“ diese

Behälter wäre „sieht“, dass Sie die Bohne als BMT

markiert haben

so irgendwann Sie vermutlich Usertransaction-Objekt verwenden würde und seine beginnen/Commit/Rollback etc Methoden

Und da truely verschachtelte Transaktionen werden nicht von WebLogic/oracle etc .. unterstützt Container hat keine andere Wahl, aktuelle Transaktion zu suspendieren die neue

der Lage sein, zu unterstützen 10

Bei CMT - da Sie erfordert die Verwendung oder RequiredNew - Container „weiß“ Ihre Absicht und choses derselben Transaktion fortzusetzen, oder zu suspendieren und eine neue starten entsprechend

0

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"

0

ich eine kleine Suche auf das tat, ist unter dem Strich, dass -ähnlichen was @kalpesh sagte Soni oben Container knows exactly what It's doing to propagate the transaction, but leaving it to you, It's expected that you might create a scenario that causes problems due to the details of the underlying server that you use direclty ... In this link beschreibt der Schreiber ein bestimmtes Szenario, das ein Problem speziell mit weblogic + ein Freak-Anwendungsverhalten macht .... Er erklärt auch, wie diese Funktionalität verfügbar ist, aber nicht in der UserTransaction Schnittstelle direkt, aber in einer seiner Implementierungen