Inter Bean Communication:J2EE Transactions
Hi,
I have an application flow like this.
{[EJB A]-->[EJB Adaptor]}-->[EJB B]
Because of some exception in [EJB B], the transaction is rolled back. In the EJB Adaptor method how can I find whether [EJB B] has rolled back the transaction. [EJB Adaptor] is packaged in the [EJB A] EAR.
I am using container managed transaction.
If I would have been in the been class, I would have used the SessionContext to read the transaction state.
Any suggestions will be helpful.
Thanks in advance.
Cheers,
Amod
[565 byte] By [
IvoryDomea] at [2007-11-26 16:15:22]

# 1
Hi Amod,
If EJB Adaptor is not an EJB it is treated as a utility class, which means it is running within the
scope of the EJB A component.In EJB 3, the SessionContext can be defined as a resource
dependency that can be injected or looked up via JNDI.Lookup would be necessary in your
case since basic utility classes do not support injection. So, in your EJB A bean class, add the
following :
@Resource(name="sesCtx") SessionContext ctx;
Then, in your utility code :
SessionContext ctx = (SessionContext) new InitialContext().lookup("java:comp/env/sesCtx");
Note how the name relative to java:comp/env is the same as the @Resource name attribute.
One other thing to note is that it is typically recommended that code that is explicitly
calling setRollbackOnly() throw an ApplicationException to notify the code
up in the chain that a problem occurred. This is preferable to requiring that all the
code before you must always check if the tx has been marked for rollback after each
call.
--ken
# 2
Thanks Ken.
Since [EJBAdaptor] is in [EJB A] context and it's a global transaction, if we can read the transaction state of [EJB A], wouldn't this help?
If yes, is there any other way apart from looking up [EJB A]'s SessionContext through JNDI?
In [EJB B] even if the transaction rolls back it has to return a response. It can not throw Exception.
Cheers
# 3
> Since [EJBAdaptor] is in [EJB A] context and it's a
> global transaction, if we can read the transaction
> state of [EJB A], wouldn't this help?
Not sure I understand the question. There isn't any specific notion of exposing
a particular EJB's transaction state. There is only the state of the current
global transaction itself, which may be associated with more than one EJB
in the current invocation path.The main reason I mentioned the fact that
EJBAdaptor is running within the context of EJB A is because the component
environment is scoped at the EJB level, so any environment dependencies
looked up by EJB Adaptor must be defined for EJB A.
>
> If yes, is there any other way apart from looking up
> [EJB A]'s SessionContext through JNDI?
One alternative is
javax.transaction.TransactionSynchronizationRegistry
http://java.sun.com/javaee/5/docs/api/
It was mainly created for use by system components but it's
allowable for use by the application.Of course, that is accessible
by JNDI too so you'd still be doing a lookup. The advantage is
it's always available at a well-known location (listed in the JavaDoc)
so you wouldn't need to declare your own env dependency.
>
> In [EJB B] even if the transaction rolls back it has
> to return a response. It can not throw Exception.
Fair enough. One thing that often surprises developers though is that
once the tx has been marked for rollback any transactional piece of
work that is attempted within the tx can fail eagerly and thus throw a
system exception.Basically, "all tx bets are off" once the tx has been
marked for rollback :-)
--ken
>
> Cheers
# 4
Not sure I understand the question. There isn't any specific notion of exposing
a particular EJB's transaction state. There is only the state of the current
global transaction itself, which may be associated with more than one EJB
in the current invocation path. The main reason I mentioned the fact that
EJBAdaptor is running within the context of EJB A is because the component
environment is scoped at the EJB level, so any environment dependencies
looked up by EJB Adaptor must be defined for EJB A.
--[Amod] You have got by doubt very much right :). Since EJBAdaptor is running in the context of EJBA and we have a global transaction, we should have a method to get know the state of the transaction.
It may look funny, but I am talking something like Thread class currentThread method. JTA should have some API to read the state of the current transaction. I hope all J2EE applications adhere to JTA!!!
# 5
> --[Amod] You have got by doubt very much right :).
> Since EJBAdaptor is running in the context of EJBA
> and we have a global transaction, we should have a
> method to get know the state of the transaction.
> It may look funny, but I am talking something like
> Thread class currentThread method. JTA should have
> some API to read the state of the current
> transaction. I hope all J2EE applications adhere to
> JTA!!!
Yes, that's essentially what both the EJBContext and TransactionSynchronizationRegistry
getRollback implementations are doing. Under the covers there is some thread-local state
for the current global transaction.
# 6
> Yes, that's essentially what both the EJBContext and TransactionSynchronizationRegistry
getRollback implementations are doing.
1. EJBContext reference is avavilable for the Bean Instance only.
2. TransactionSynchronizationRegistry is available from JTA 1.1(J2EE 1.4)
If I am in the same context, the bean like a wrapper, why I should look for EJBContext or TransactionSynchronizationRegistry through lookup. Don't you agree with me that there should be a class with a method to get the transaction state of any J2EE application?
# 7
I don't quite understand the concern.Web applications and BMT ejbs
already have direct control over the transaction via the UserTransaction object.
For ejbs with container-managed transactions, it is typically the bean class that is
in the best position to determine whether to mark the tx for rollback, so EJBContext
is a convenient way to do it.If utility classes have the same need, they already
have two ways to accomplish it.I don't see a compelling need to add a third.
--ken