Skip to main content

Client transaction aborted?

6 replies [Last post]
ljnelson
Offline
Joined: 2003-08-04
Points: 0

I have an application using XA. I know, I know.

There is an EJB that has two methods on it. Both do a simple find on an
entity.

Both methods log entry and exit.

Both use TransactionAttributeType.SUPPORTS.

The first one works fine. I see log output.

The second one, invoked from the same method and transaction context as the
first one, does not even get entered, and no amount of logging in the EJB
uncovers a problem. There is in fact no log output at all. The GlassFish
error I get is:

[#|2013-08-22T13:27:07.838-0400|WARNING|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=22;_ThreadName=Thread-5;|javax.ejb.TransactionRolledbackLocalException:
Client's transaction aborted
at com.sun.ejb.containers.BaseContainer.useClientTx(BaseContainer.java:4722)
at com.sun.ejb.containers.BaseContainer.preInvokeTx(BaseContainer.java:4616)
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1914)
at
com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
at
com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
at com.sun.proxy.$Proxy327.getDisplayNameType(Unknown Source)

There is no other diagnostic information I can cause GlassFish to output,
because the error is somewhere in the proxy's invocation of my local bean
(I think?).

The local bean is created (I logged the constructor information).

Where should I begin looking to uncover the root cause of this error? Is
there a particular GlassFish logging level I can dial up that would give me
more information?

The only extant post out there that I found that even remotely seems like
this error is here: https://forums.oracle.com/thread/2130658

Best,
Laird

--
http://about.me/lairdnelson

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
ljnelson
Offline
Joined: 2003-08-04
Points: 0

On Thu, Aug 22, 2013 at 1:37 PM, Laird Nelson wrote:

> The only extant post out there that I found that even remotely seems like
> this error is here: https://forums.oracle.com/thread/2130658
>

I tried upping the thread pool max as outlined in that post to no avail.
I'm not surprised; that sounded like closing your eyes and blasting away
with a shotgun trying to hit the problem. Oh well!

Here is how the error is getting triggered:

NameType displayNameType = null;
assert this.nameTypeManager != null;
try {
displayNameType = this.nameTypeManager.getDisplayNameType(); // (1)
} catch (final RuntimeException wtf) {
this.logger.throwing(this.getClass().getName(), "createDisplayName",
wtf); // (2)
throw wtf;
}

nameTypeManager in this case is a local stateless session bean. Other
methods that executed during this same transaction ran fine.

At (1), debugging will not drop me into getDisplayNameType(). In that
method, the first statement is a logger.entering() call. This call is
never reached.

At (2), this logging output does not show up, even though other logger
output at the same level (FINER) does. (?!) Not sure how transaction
issues could affect the logging system, but there you go.

Best,
Laird

--
http://about.me/lairdnelson

ljnelson
Offline
Joined: 2003-08-04
Points: 0

On Thu, Aug 22, 2013 at 2:41 PM, Laird Nelson wrote:

> At (1), debugging will not drop me into getDisplayNameType(). In that
> method, the first statement is a logger.entering() call. This call is
> never reached.
>

I got around this by changing the transaction attribute type to
TransactionAttributeType.NOT_SUPPORTED. Then the very next method call in
the current transaction (a different EJB this time) results in the same
exception.

What causes the client transaction to abort? Why is a rollback exception
devoid of a root cause?

Best,
Laird

--
http://about.me/lairdnelson

ljnelson
Offline
Joined: 2003-08-04
Points: 0

On Thu, Aug 22, 2013 at 5:00 PM, Laird Nelson wrote:

> What causes the client transaction to abort? Why is a rollback exception
> devoid of a root cause?
>

The root cause for posterity: EntityManager#contains(Object), if passed an
object that is not known to the EntityManager, will throw an
IllegalArgumentException. The throwing of this exception marks the
transaction for rollback. There is no way to blindly test an arbitrary
object to see if the EntityManager has it in its persistence context--you
must only test the subset of objects that are known to that EntityManager.
When you're working with XA, there are two entity managers in play
(usually) so "knowing" this up front in the code is often difficult.

I wish a "test" method like this ("is everything OK?") didn't roll back the
active transaction. Maybe there's some way to roll a contains() method out
of the metamodel that would not throw an exception on an unknown object....

Best,
Laird

--
http://about.me/lairdnelson

mvatkina
Offline
Joined: 2005-04-04
Points: 0

This might be a good candidate for both, the EJB and the JPA spec
updates. The EJB spec should a) describe the behavior of business method
invocations in a transaction marked for rollback, and b) allow to check
rollback status in a SUPPORTS method if there is a transaction in progress.

-marina

On 8/27/13 10:40 AM, Laird Nelson wrote:
> On Thu, Aug 22, 2013 at 5:00 PM, Laird Nelson > wrote:
>
> What causes the client transaction to abort? Why is a rollback
> exception devoid of a root cause?
>
>
> The root cause for posterity: EntityManager#contains(Object), if
> passed an object that is not known to the EntityManager, will throw an
> IllegalArgumentException. The throwing of this exception marks the
> transaction for rollback. There is no way to blindly test an
> arbitrary object to see if the EntityManager has it in its persistence
> context--you must only test the subset of objects that are known to
> that EntityManager. When you're working with XA, there are two entity
> managers in play (usually) so "knowing" this up front in the code is
> often difficult.
>
> I wish a "test" method like this ("is everything OK?") didn't roll
> back the active transaction. Maybe there's some way to roll a
> contains() method out of the metamodel that would not throw an
> exception on an unknown object....
>
> Best,
> Laird
> --
> http://about.me/lairdnelson

ljnelson
Offline
Joined: 2003-08-04
Points: 0

On Tue, Aug 27, 2013 at 2:16 PM, Marina Vatkina
wrote:

> The EJB spec should a) describe the behavior of business method
> invocations in a transaction marked for rollback
>

Yes, please.

> [...] and b) allow to check rollback status in a SUPPORTS method if there
> is a transaction in progress.
>

Oh, this is not possible?

I don't disagree with you, but how would (b) help? Are you suggesting
allowing business methods that require or support a transaction to be
entered, even though they can't really do anything?

(I'd actually like to see EntityManager#contains(Object) relaxed to simply
return false if the object it is passed is not even known to it. But I'm
sure that has all sorts of other implications.)

Best,
Laird

--
http://about.me/lairdnelson

mvatkina
Offline
Joined: 2005-04-04
Points: 0

On 8/27/13 11:47 AM, Laird Nelson wrote:
> On Tue, Aug 27, 2013 at 2:16 PM, Marina Vatkina
> > wrote:
>
> The EJB spec should a) describe the behavior of business method
> invocations in a transaction marked for rollback
>
>
> Yes, please.

File a JIRA ;)
>
> [...] and b) allow to check rollback status in a SUPPORTS method
> if there is a transaction in progress.
>
>
> Oh, this is not possible?

E.g.

8.6.3.9 Handling of getRollbackOnly Method

The container must handle the EJBContext.getRollbackOnly method invoked
from a business method executing with the REQUIRED, REQUIRES_NEW, or
MANDATORY transaction attribute.

The container must throw the java.lang.IllegalStateException if the
EJBContext.getRollbackOnly method is invoked from a business method
executing with the SUPPORTS, NOT_SUPPORTED, or NEVER transaction attribute.

>
> I don't disagree with you, but how would (b) help? Are you suggesting
> allowing business methods that require or support a transaction to be
> entered, even though they can't really do anything?

It just seems too restrictive (in other places the spec says "Invoking
the getRollbackOnly and setRollbackOnly methods is disallowed in the
session bean methods for which the container does not have a meaningful
transaction context").

Best,
-marina

>
> (I'd actually like to see EntityManager#contains(Object) relaxed to
> simply return false if the object it is passed is not even known to
> it. But I'm sure that has all sorts of other implications.)
>
> Best,
> Laird
>
> --
> http://about.me/lairdnelson