users@javaee-spec.java.net

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

From: Werner Keil <werner.keil_at_gmail.com>
Date: Fri, 13 Jul 2012 14:38:03 +0200

Sounds like a good idea.

Although JPA's own exceptions fall into that category, let's say a project
wants to exclude unchecked (runtime) exceptions,
@Transactional(
  rollbackOn={SQLException.**class, ApplicationException.class},
  dontRollbackOn={RuntimeException.**class}
)

may work.

Ideally applications should have an even finer grained exception hierarchy.

Werner


On Fri, Jul 13, 2012 at 7:15 AM, Markus Eisele <myfear_at_web.de> wrote:

> Hi Linda/all,
>
> that's a good step! +1
>
> - Markus
>
> On 13 July 2012 03:00, Linda DeMichiel <linda.demichiel_at_oracle.com> 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?
>



-- 
 Werner Keil | JCP Executive Committee Member | Eclipse UOMo Lead
 Twitter @wernerkeil | #Java_Social | #EclipseUOMo | #OpenDDR
Skype werner.keil | Google+ gplus.to/wernerkeil
* Chip-to-Cloud Security Forum: September 19 2012, Nice, French Riviera.
Werner Keil, JCP Executive Committee, JSR-321 EG Member will present
"Trusted Computing API for Java™"