Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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:

  • JPA transaction rollback fails with call to stateless bean
  • How does UserTransaction propagate?
  • How to propagate a client-side UserTransaction into a stateless session bean using BMT (the quote has been copied from there)
like image 275
Beryllium Avatar asked Jul 27 '13 13:07

Beryllium


People also ask

What is bean managed transaction in EJB?

In a bean-managed transaction, the code in the session or message-driven bean explicitly marks the boundaries of the transaction. An entity bean cannot have bean-managed transactions; it must use container-managed transactions instead.

Does EJB support distributed transaction?

The EJB specification allows for distributed transactions that span multiple resources (such as databases) and supports the two-phase commit protocol for both EJB CMP 2.0 and EJB CMP 1.1. WebLogic Server supports any JTA-compliant XA resource.

How would you check the condition of the current transaction in a bean managed transaction in EJB?

You probably know that if you use BMT (Bean Managed Transactions) you can get information about current transaction status by using UserTransaction interface (which implementation can be fetched either by JNDI or using dependency injection) and executing it's getStatus() method.

What will happen if a transactional client invokes an enterprise bean method whose transaction attribute is set to never within a transaction context?

If the client is running within a transaction and invokes the enterprise bean's method, the container throws a RemoteException. If the client is not associated with a transaction, the container does not start a new transaction before running the method.


2 Answers

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

like image 144
Kalpesh Soni Avatar answered Oct 20 '22 22:10

Kalpesh Soni


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"

like image 31
chalda Avatar answered Oct 20 '22 20:10

chalda