Why do EJB beans with bean-managed transactions act as a "transaction barrier"?
Asked Answered
T

4

6

A quote from the EJB 3.1 specification:

13.6.1 Bean-Managed Transaction Demarcation

The container must manage client invocations to an enterprise bean instance with bean-managed transaction demarcation as follows. When a client invokes a business method via one of the enterprise bean’s client views, the container suspends any transaction that may be associated with the client request.

On the other hand, a transaction from a stand-alone client or another EJB is propagated into a bean using container-managed transactions. Looking at it from the CMT perspective, it seems that beans using CMT have an additional important feature (transaction propagation).

What is the reason for this restriction ("transaction barrier") being imposed on beans using BMT?

Related questions:

Tranship answered 27/7, 2013 at 13:8 Comment(1)
An educated guess: One reason might be to avoid resource leakage in the container. It's a good rule of thumb that a class that creates a resource should also be responsible for cleaning up a resource; and if it happens that it doesn't clean up properly after exit, the container may force close all open resources opened by the EJB (e.g., open transactions) to avoid resource leakage, which would be dangerous. A related example is open file descriptors of processes in *nix, all of which will be closed by the kernel when the process exits.Wonderstricken
P
2

My "guess" would be this

container "sees" that you have marked the bean as BMT

so at some point you would presumably use UserTransaction object and its begin/commit/rollback etc methods

And since truely nested transactions are not supported by weblogic/oracle etc .. Container has no choice but to suspend current transaction to be able to support the new one

In case of CMT - since you use Requires, or RequiredNew - container "knows" your intent and choses to continue same transaction, or suspend and start a new one accordingly

Pneuma answered 12/11, 2014 at 18:44 Comment(0)
T
1

I do agree with answer by Kalpesh Soni just I would like to add bit more.

Container uses the same thread for running of one to other EJB calls. A thread could be bound with only one global transaction managed by TM. That's why @Asynchronous bean call does not propagate transaction (EJB 3.2 spec, 4.5.3 Transactions). Transaction can't be split over more threads and it's bound to the caller one.

If bean is marked as CMT then container manages transaction creations based on the annotation or info taken from ejb-jar.xml descriptor. Container is then able to decide if the bean method call will be part of the currently running transaction or a new one needs to be created. As mentioned nested transaction is not supported in most of the Java EE containers. By my understanding the main reason is that XAResource does not support nested transactions (see JTA spec).

BMT bean uses UserTransaction to drive transaction management on its own. How propagation existing transaction to BMT should work or better what you could with it then? If you would like start a new transaction with UserTransaction.begin() then the currently running one would be suspended. That's how now propagation works now. I mean transaction is not propagated but suspended at BMT bean call. The other thing that you could do is drive transaction. It means use UserTransaction.commit() or UserTransaction.rollback() on incoming transaction. If you do so then caller on return would be working with no active transaction in its context. Which means a call to a different bean could work with your transaction without you as caller knows and being notified about it. I think that you don't want this being possible. That's my understanding about reasons behind.

There is another funny thing about BMT. If you use a SLSB (Stateless Session Bean) then you are not permitted to exit the called method without finishing transaction (see EJB 3.2: 8.3.3 Enterprise Beans Using Bean-Managed Transaction Demarcation). On the other hand SFSB (Stateful Session Bean) can exit a method without finishing the transaction and that could be finished in other call. If such call happens e.g. in different HTTP session than transaction is suspended and taken from the current thread and later on activated and pinned to new thread.

javax/transaction/xa/XAResource.html "XAResource Java EE 7 API"

Teresetereshkova answered 17/2, 2016 at 17:42 Comment(0)
H
0

I did a small search on this, the bottom line is that -like what @kalpesh Soni said above- 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, the writer describes a certain scenario that make a problem specifically with weblogic + a freak application behavior .... He also expalins how this functionality is available but not in the UserTransaction interface directly but in one of its implementations

Her answered 7/8, 2017 at 15:17 Comment(0)
G
-1

When you use BMT, you manage the transaction. You use UserTransaction for create and commit the transaction.

The point here is that UserTransaction create a transaction in the current thread and when you call another EJB, that call will be executed in another thread (with its own EJB's life cycle).

In CMT, the container interpose on the method invocation for handling the transaction.

3.1 UserTransaction Interface (From JTA specification)

The UserTransaction.begin method starts a global transaction and associates the transaction with the calling thread. The transaction-to-thread association is managed transparently by the Transaction Manager.

Support for nested tranactions is not required. The UserTransaction.begin method throws the NotSupportedException when the calling thread is already associated with a transaction and the transaction manager implementation does not support nested transactions.

3.2.2 Completing a Transaction

The TransactionManager.commit method completes the transaction currently associated with the calling thread. After the commit method returns, the calling thread is not associated with a transaction. If the commit method is called when the thread is not associated with any transaction context, the TM throws an exception.

13.2.5 Container-Managed Demarcation (From EJB specification)

Whenever a client invokes a method on an enterprise bean’s business interface (or on the no-interface view or home or component interface of an enterprise bean), the container interposes on the method invocation. The interposition allows the container to control transaction demarcation declaratively through the transaction attribute set by the developer.

Grandfather answered 9/11, 2014 at 2:57 Comment(6)
When an EJB using CMT calls another EJB using CMT, that one has it's own life cycle as well. So why does it work in that case? As for "that call will be executed in another thread": Could you point out the relevant section in the spec where this is defined? In other words, is it really another thread? In case of an EJB calling another EJB there is no other thread AFAIK.Tranship
I have updated my answer with a more detailed answer. Let's me now what do you think about that answerGrandfather
I also have issue with this assertion "when you call another EJB, that call will be executed in another thread" - I dont think this is a requirementPneuma
4.10.13 Non-reentrant Instances (From EJB Specification) The container must ensure that only one thread can be executing a stateless or stateful session bean instance at any time. Therefore, stateful and stateless session beans do not have to be coded as reentrant. One implication of this rule is that an application cannot make loopback calls to a stateless or stateful session bean instance.Grandfather
so two threads cannot enter one session bean instance, but one thread CAN enter two session bean instances :DPneuma
you haven't marked the question as answered, is there another question?Grandfather

© 2022 - 2024 — McMap. All rights reserved.