[javaee-spec users] Re: [jsr342-experts] transactional interceptors and exceptions

From: Paul Robinson <>
Date: Sat, 14 Jul 2012 15:46:50 +0100


So it looks like we are settling on adopting almost the same approach for exception handling as that currently provided by EJB. I'll quote my previous email on this:

My personal thoughts are that we really have to provide the same behaviour as that provided by EJB transactional intercepters (D3 S2c A1). As this is a JEE related specification, users are going to find it very strange that the semantics of these, seemingly identical, annotations are different. More dangerously, there are going to be many users who don't know that the semantics around exception handling and rollback are different, potentially causing the behaviour of there application to change in unexpected ways.

However, the proposal does differ in how non-default behaviour is expressed. By offering S3c rather than S2c, we are going to cause potentially unexpected behaviour for those migrating away from EJB. I would expect that many developers will leave the annotations on the Exception classes, expressing a change from the default, and expect those to be adhered to. Unfortunately, with the S3c approach these old annotations will be ignored along with the developer's intend behaviour. My feeling is that in many (most?) applications, this is the type of bug that is unlikely to be detected during testing and is likely to surface at runtime.

My understanding is that EJB and the TX interceptors will co-exist for some time, so we can't prevent this type of issue by simply preventing the EJB related transaction annotations being placed on an Exception class.

Do we really need to move away from the accepted and well understood behaviour of EJB?


On 13 Jul 2012, at 02:00, Linda DeMichiel wrote:

> We'd like to close out the remaining open issue as to how to
> specify the behavior of transactional interceptors when an
> exception is thrown that reaches such an interceptor.
> After tallying and weighing the responses that we received from
> polling this group, from our other Java EE specleads, and from members
> of the community, we propose that we take the "D3 S3C A1" approach
> -- which is consistent with the majority of the opinions we received.
> (To refresh your memory, please see Bill's earlier message, appended below.)
> The proposal is the following:
> By default, "application exceptions" (i.e., checked exceptions /
> instances of Exception and its subclasses other than RuntimeException)
> do not result in the transactional interceptor marking the transaction
> for rollback, and instances of RuntimeException and its subclasses do.
> This default behavior can be overridden via the Transactional
> annotation. More specifically, we propose adding to the
> Transactional annotation an element to specify additional
> exceptions that result in the interceptor marking the
> transaction for rollback and an element to specify exceptions
> that do not cause the interceptor to mark the transaction for rollback.
> For example:
> @Inherited
> @InterceptorBinding
> @Target({TYPE, METHOD})
> @Retention(RUNTIME)
> public @interface Transactional {
> TxType value() default TxType.REQUIRED;
> Class[] rollbackOn() default {};
> Class[] dontRollbackOn() default {};
> }
> When a class is specified for either of these elements, the
> designated behavior applies to subclasses of that class as well.
> If both elements are specified, dontRollbackOn takes precedence.
> Examples:
> @Transactional(rollbackOn={Exception.class})
> will override behavior for application exceptions, causing the
> transaction to be marked for rollback for all application exceptions.
> @Transactional(dontRollbackOn={IllegalStateException})
> will prevent transactions from being marked for rollback by the
> interceptor when an IllegalStateException or any of its subclasses
> reaches the interceptor.
> @Transactional(
> rollbackOn={SQLException.class},
> dontRollbackOn={SQLWarning.class}
> )
> will cause the transaction to be marked for rollback for all
> runtime exceptions and all SQLException types except for SQLWarning.
> Note that we are assuming that there is no special, built-in knowledge
> about EJB application exceptions (i.e., runtime exceptions annotated
> with @ApplicationException). As far as the interceptor is concerned,
> these would be treated just as any other runtime exceptions unless
> otherwise specified.
> Please let us know if you have any additional feedback on this.
> thanks!
> -Linda
> --------------------------------
> On 1/30/2012 12:40 PM, Bill Shannon wrote:
>> 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?

Paul Robinson
Web service transactions lead
JBoss, a Division of Red Hat
Registered in England and Wales under Company Registration No. 03798903
Directors: Michael Cunningham (USA), Brendan Lane (Ireland), Matt Parson
(USA), Charlie Peters (USA)