users@ejb-spec.java.net

[ejb-spec users] [jsr345-experts] Fwd: [jsr342-experts] transactional methods and exceptions

From: Linda DeMichiel <linda.demichiel_at_oracle.com>
Date: Thu, 02 Feb 2012 11:35:21 -0800

The EJB expert group obviously has a lot of experience with container-managed
transactions. As noted earlier in the messages Marina forwarded to this list
from the Java EE Platform EG, in Java EE 7 we're trying to broaden the facility
in terms of transactional interceptors, with the intent that these be made
applicable to all of our EE component types as well as to CDI managed beans.

There has been general acceptance of our earlier proposal, but there are
still a few details to be ironed out, and we're trying to get more
feedback from members of the community on these.

The first of these pertains to how to handle the exceptions that
are thrown from a method that has a transactional interceptor.

Bill's message below outlines the choices that we see. We'd appreciate
your feedback on these. Please post either here, on the users list, or
on the javaee-spec users list.

thanks,

-Linda



-------- Original Message --------
Subject: [jsr342-experts] transactional methods and exceptions
Date: Mon, 30 Jan 2012 12:40:13 -0800
From: Bill Shannon <bill.shannon_at_oracle.com>
Reply-To: jsr342-experts_at_javaee-spec.java.net
To: jsr342-experts_at_javaee-spec.java.net

One of the issues with the new transactional annotations we're
proposing is how to handle exceptions that are thrown out of a
transactional method.

The first choice is, what should the default behavior be?
We have these options:

D1. By default, exceptions don't effect the current transaction.
D2. By default, exceptions cause the current transaction to be
     marked for rollback.
D3. By default, runtime exceptions cause the current transaction to be
     marked for rollback; checked exceptions do not effect the current
     transaction.

After deciding on the default behavior, we have these choices for
overriding the default:

S1. You can't override the default.
S2a. You can override the default by annotating exceptions that
      should cause rollback. (E.g., with @ApplicationException)
S2b. You can override the default by annotating exceptions that
      should not cause rollback.
S2c. You can override the default by annotating exceptions that
      should cause rollback and by annotating exceptions that should
      not cause rollback. (E.g., with a "rollback" element in
      @ApplicationException)
S3a. You can override the default by annotating class or methods
      with a list of exceptions that should cause rollback.
S3b. You can override the default by annotating class or methods
      with a list of exceptions that should not cause rollback.
S3c. You can override the default by annotating class or methods
      with a list of exceptions that should cause rollback, and a
      list of exceptions that should not cause rollback.

The S2c and S3c options have these additional options:

A1. The rollback behavior is an element(s) of the base annotation.
A2. The rollback behavior is a separate annotation(s).

(Note that S2 and S3 are not mutually exclusive.)

In all cases, the behavior for a given exception is determined by
looking for an annotation or specification for that particular
exception and if none is found traversing the superclass chain.
That is, the exception behavior is always "inherited".


My understanding is that Spring supports D3 S3c A1.
(In addition, Spring allows specifying the exceptions as either
Class objects or String names, which seems like overkill.)

EJB supports D3 S2c A1 for local beans.

I believe Reza was suggesting D3 S2c S3c A1.

I believe David was suggesting D1 S3a A2.

Our goal with these new transactional annotations was to come up
with something that was simple, where "simple" means both "has
few concepts" and "is easily understood by developers". In addition
to being simple, it needs to satisfy a large percentage of the use cases.

The simplest is D1 S1, but I don't think that matches what developers
will expect.

Given the prevalence of D3 in existing systems, D3 S1 would be very
simple. Unfortunately, we're told that many developers are moving
towards using runtime exceptions for everything, so D3 S2b would be
a relatively simple approach.

The major advantage I see for the S3 options is that they allow you
to more easily override the default behavior for "system" exceptions.
For example, if your method throws IllegalArgumentException in a case
where it knows that it hasn't modified the state of the transaction,
you might like that exception to *not* cause the transaction to be
marked for rollback. With S2, you would have to subclass the exception
and mark the subclass. But of course that does have the advantage
that other uses of that exception in methods you call have the default
behavior.

Which options do you prefer?