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

左心房为你撑大大i 提交于 2019-12-19 07:49:58

问题


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)

回答1:


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




回答2:


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"




回答3:


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




回答4:


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.



来源:https://stackoverflow.com/questions/17898154/why-do-ejb-beans-with-bean-managed-transactions-act-as-a-transaction-barrier

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!