Skip to main content

[jsr342-experts] Re: Transactional interceptors and exceptions

  • From: "Deepak Anupalli" <deepak@...>
  • To: <jsr342-experts@...>
  • Subject: [jsr342-experts] Re: Transactional interceptors and exceptions
  • Date: Tue, 31 Jan 2012 13:39:43 +0530

Bill, I happened to send this mail yesterday but it failed, so I resent it
in the morning without reading the other mails. Yes, it addresses all the
concerns I had in the context of EJBs.

-Deepak

-----Original Message-----
From: Bill Shannon [mailto:bill.shannon@...] ;
Sent: 31 January 2012 13:03
To: jsr342-experts@...
Subject: [jsr342-experts] Re: Transactional interceptors and exceptions

Did you see my other message from today?  It addresses this issue.

Deepak Anupalli wrote on 01/30/2012 08:54 PM:
> May be a lame question, but can the transactional interceptor be 
> applied to an EJB component as well?
>
> If so, are these exception handling rules going to be confusing when 
> we have an EJB directly invoking another EJB (vs) EJB invoking another 
> EJB through the interceptor?
>
> -Deepak
>
> -----Original Message-----
> From: David Blevins [mailto:david.blevins@...]
> Sent: 24 January 2012 03:30
> To: jsr342-experts@...
> Subject: [jsr342-experts] Re: Transactional interceptors and 
> exceptions
>
>
> On Jan 20, 2012, at 4:51 PM, David Blevins wrote:
>
>> I don't have a good vision for how separating them would be done, but 
>> I
> wonder if it's just as simple as having a "Transaction" interceptor 
> and a "RollbackOnException" interceptor.  Or some variation on the idea.
>
> This idea came to me as a self-documenting and very flexible possible
> approach:
>
>     @Transactional
>     @Rollback({RuntimeException.class, MyCustomException.class})
>     public void doSomething() {
>         //...
>     }
>
> If the exception is assignable to anything in the list, the 
> transaction is rolled back.  At this point there isn't the need for 
> @ApplicationException or anything similar.  Just about anyone could 
> look at that and know what's going on and how to alter the behavior.
>
> That's probably good enough right there.
>
> In the future if we get some generally applicable pattern for 
> annotation reuse in place (e.g. meta-annotations, more generic version 
> of stereotype, whatever want to call it), these common combinations can be
easily reused:
>
>     @Transactional
>     @Rollback({RuntimeException.class, MyCustomException.class})
>     @RolesAllowed({"Manager", "Admin"})
>     @Metatype
>     @Target(ElementType.TYPE)
>     @Retention(RetentionPolicy.RUNTIME)
>     public @interface AcmeTransactionalOperation {
>     }
>
> Then..
>
>     @AcmeTransactionalOperation
>     public void doSomething() {
>         //...
>     }
>
> Effectively, the problem of what we need to squish together for 
> convenience isn't our problem anymore.  We just focus on clear and
separate concerns.
> With some ability to compose things together, the question of "will 
> users also want x with y" where the answer is clearly "sometimes" 
> becomes an easy one for users to solve for themselves.
>
> At that point we as spec designers need to only ask "will users want x 
> and possibly not y".  And of course, there'd be some flexibility to 
> get that answer wrong.  If we learn annotation X encompasses too much 
> functionality (the "i got more than I wanted" problem), we could of 
> course split those concerns into annotations D and E then redefine X 
> as a meta-annotation comprised of D and E.
>
>
> -David
>
>
>> I can see concrete use cases for people wanting the protection of
> MANDATORY and having the mindset of, "Look, it's your transaction, 
> deal with the exceptions as you see fit.  Don't make me tell you 
> what's safe and isn't."
>>
>> Of course the concept of app/system exceptions could still be 
>> supported
> for when people opt-into the "RollbackOnException" contract, though I 
> wonder if it would be all that used.  Theoretically, if you had 
> specific goals for your exception handling, you could simply assume 
> that responsibility.  Don't use the standard "RollbackOnException" 
> interceptor and instead write your own interceptor to call 
> setRollbackOnly() using whatever conditions you wanted.  With things
separated, you'd have this ability, with them "smushed"
> together you'd have to write all your own transaction handling code.
>>
>> A lot of things can simply be traced back to the fact that 
>> interceptors
> did not exist when these particular APIs were created.
>>
>> For as large as the CMT API is it's actually not that complete.  For
> example, why not an interceptor that calls getRollbackOnly() and 
> throws a "DontBotherInvokingMeException" if the answer is false?  Was 
> probably not worth the xml before and perhaps not worth annotation 
> now, but it's an interesting omission.
>>
>>> I definitely agree with you about the SFSB destruction issue flagged 
>>> in your blog.  I would advocate that we try to fix that for the
>>> transactional interceptor case.   We could try to fix it in general
>>> with the introduction of more metadata, if the EJB EG wants.
>>
>> Will definitely give that some thought.
>>
>>>
>>>>
>>>> Not a proposal, but some thoughts.
>>>>
>>>
>>> thanks again for posting
>>
>> Thanks for tackling this topic.  It's a fun one.  We could certainly 
>> green-light the CMT API as-as with no harm, but there's no denying we 
>> won't get this chance again for quite a long time :)
>>
>>
>> -David
>>
>>>>>
>>>>> Jan 18, 2012 07:53:44 PM, jsr342-experts@... wrote:
>>>>> Supporting a superset of Spring and EJB would result in something 
>>>>> very complex. In particular, the way Spring allows control over 
>>>>> the rollback behavior using include lists and exclude lists and 
>>>>> class names and Class objects is very complex. We were hoping to 
>>>>> satisfy most developers with something much simpler than Spring or
EJB.
>>>>>
>>>>> Which of the features from Spring's @Transactional annotation do 
>>>>> you think are the most used?
>>>>>
>>>>> reza_rahman@... wrote on 01/17/12 09:47:
>>>>>> Sorry for the delay in responding. Things are hectic these days...
>>>>>>
>>>>>> I actually think EJB 3 application vs. system exception is a good 
>>>>>> idea (except for that I don't think the special treatment of 
>>>>>> RemoteException is really needed
>>>>>> -- in Spring, system exception == runtime exception). It's easy 
>>>>>> to explain, works in the real world and corresponds nicely with 
>>>>>> exception handling best
>>>>>> practices:
> http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html?page=1.
>>>>>> Now, I do think it would be very useful to provide a mechanism to 
>>>>>> override default exception level behavior (no
>>>>>> annotation/checked/unchecked/@ApplicationException) per 
>>>>>> bean/method. Basically, I would like to see the super-set of 
>>>>>> Spring 
>>>>>> (http://static.springsource.org/spring/docs/2.0.x/api/org/springf
>>>>>> r
>>>>>> amework/transaction/annotation/Transactional.html)
>>>>>> and EJB exception handling.
>>>>>>
>>>>>> As to wrapping exceptions, I do agree it's completely overkill 
>>>>>> and counter-intuitive (Spring does not do it, for example).
>>>>>>
>>>>>> Hope it helps.
>>>>>>
>>>>>> Jan 10, 2012 03:14:50 PM, jsr342-experts@...
>>>>>> <mailto:jsr342-experts@...>   wrote:
>>>>>>
>>>>>>
>>>>>> It looks like we're in general agreement on the transactional 
>>>>>> interceptor approach I proposed earlier.
>>>>>>
>>>>>> Aside from the more obvious open issues around naming, there is 
>>>>>> an issue related to the handling of exceptions that we need to
resolve.
>>>>>>
>>>>>> The issue relates to what should happen with regard to the state 
>>>>>> of a transaction when an exception is thrown that reaches a 
>>>>>> transactional interceptor.
>>>>>>
>>>>>>
>>>>>> First, some background on how EJB handles container-managed
> transactions....
>>>>>>
>>>>>> The EJB spec distinguishes between "system exceptions", which 
>>>>>> cause the container to mark the transaction for rollback, and 
>>>>>> "application exceptions", which by default do not cause the 
>>>>>> transaction to be marked for rollback.
>>>>>>
>>>>>> An application exception is either a checked exception (other 
>>>>>> than the
>>>>>> RemoteException) or a runtime exception annotated with
> @ApplicationException.
>>>>>>
>>>>>> @Target(TYPE) @Retention(RUNTIME) public @interface 
>>>>>> ApplicationException {
>>>>>>
>>>>>> /**
>>>>>> * Indicates whether the container should cause the transaction to
>>>>>> * rollback when the exception is thrown.
>>>>>> */
>>>>>> boolean rollback() default false;
>>>>>>
>>>>>> /**
>>>>>> * Indicates whether the application exception designation should
>>>>>> * apply to subclasses of the annotated exception class.
>>>>>> */
>>>>>> boolean inherited() default true; }
>>>>>>
>>>>>>
>>>>>> An EJB system exception is a subclass of RemoteException or a
>>>>>> subclass of RuntimeException that has not been designated as an
>>>>>> application exception.
>>>>>>
>>>>>> When the EJB container intercepts a system exception (at a
>>>>>> business method boundary), it causes the current transaction to be
>>>>>> marked for rollback. When the called method runs in the context of
>>>>>> the caller's transaction, the container throws the
>>>>>> EJBTransactionRolledBackException (or some variant thereof). If a
>>>>>> new transaction was *started* for the called method, the container
>>>>>> throws the EJBException. In both these cases, the original
>>>>>> exception is wrappered. Application exceptions are thrown back to the
> caller as is.
>>>>>>
>>>>>> If the caller receives an application exception, the caller
>>>>>> presumably knows based on the exception type whether the exception
>>>>>> causes rollback or not. Unless the caller is familiar with the
>>>>>> transaction attribute of the called method, however, the caller
>>>>>> doesn't know whether its own transaction was marked for rollback
>>>>>> or whether only the callee's transaction was rolled back. However,
>>>>>> the caller can invoke the getRollbackOnly method to determine the
>>>>>> state of its own transaction.
>>>>>>
>>>>>> In the case of a system exception, if the caller receives the
>>>>>> EJBException, the caller can assume that the callee's transaction
>>>>>> was rolled back, but that the caller's own transaction was not
> affected.
>>>>>> If the caller receives the EJBTransactionRolledBackException, the
>>>>>> caller knows that its own transaction was marked for rollback (and
>>>>>> that the callee was run within the context of that same transaction).
>>>>>>
>>>>>>
>>>>>> So much for background.... Now, what should the behavior be for
>>>>>> transactional interceptors?
>>>>>>
>>>>>> While we could adopt the EJB approach (modulo some renaming), Bill
>>>>>> and I are concerned that it is too complex. (See Chapter 14
>>>>>> ("Exception
>>>>>> Handling") of the EJB 3.1 spec for the gory details.)
>>>>>>
>>>>>> We propose a simpler approach along the following lines:
>>>>>>
>>>>>> By default, all exceptions should result in the current
>>>>>> transaction being marked for rollback. If the developer believes
>>>>>> that the exception should not cause rollback, he or she annotates
>>>>>> the exception class with @DontRollbackTransaction (real name for this
> exception *TBD*).
>>>>>>
>>>>>> The DontRollbackTransaction annotation is simply:
>>>>>>
>>>>>> @Target(TYPE)
>>>>>> @Retention(RUNTIME)
>>>>>> @Inherited
>>>>>> public @interface DontRollbackTransaction {}
>>>>>>
>>>>>> All exceptions are thrown back without any wrappering. While we
>>>>>> can understand the rationale for wrappering an exception that
>>>>>> marks the caller's transaction for rollback in a
>>>>>> TransactionRolledbackException, we're not convinced that this is
>>>>>> needed. Likewise, we're not convinced of the need to make a
>>>>>> distinction by means of exception wrappering as to whether the
> callee's transaction was rolled back.
>>>>>>
>>>>>>
>>>>>> We'd like your feedback on this and on your experience with regard
>>>>>> to how developers are actually making use of the current EJB
>>>>>> facility, particularly in view of the assumptions that we are making.
>>>>>>
>>>>>> Again, we are assuming the following:
>>>>>>
>>>>>> (1) It is not essential that the caller be able to identify from
>>>>>> an exception that it receives whether its own transaction was
>>>>>> marked for rollback, as the caller can use the getRollbackOnly
>>>>>> method to determine this.
>>>>>>
>>>>>> (2) It is not essential that the caller be able to identify by
>>>>>> means of the exception that it receives back whether a transaction
>>>>>> was started on behalf of a method that it invoked, as it can use
>>>>>> its knowledge of the exception received and getRollbackOnly status
>>>>>> to determine this if it does not already know this information.
>>>>>>
>>>>>> (3) Subclasses of dont-rollback exceptions will typically be
>>>>>> dont-rollback exceptions, and, if not, they can be defined to not
>>>>>> extend dont-rollback exceptions. (Note that if we receive
>>>>>> compelling feedback from developers to the contrary on this point,
>>>>>> we could always add a an element to the annotation to control this
>>>>>> at a later time. If we think this is at all likely, we should
>>>>>> choose an annotation name accordingly.)
>>>>>>
>>>>>>
>>>>>> Please post your feedback.
>>>>>>
>>>>>> Other specleads should feel free to forward this message to your
>>>>>> expert groups for further input.
>>>>>>
>>>>>>
>>>>>> thanks,
>>>>>>
>>>>>> -Linda
>>>>>>
>>>>>
>>>>
>>
>



[jsr342-experts] Re: Transactional interceptors and exceptions

(continued)

[jsr342-experts] Re: Transactional interceptors and exceptions

Linda DeMichiel 01/20/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

David Blevins 01/21/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

David Blevins 01/23/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

Werner Keil 01/23/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

David Blevins 01/23/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

David Blevins 01/23/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

David Blevins 01/23/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

David Blevins 01/23/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

Deepak Anupalli 01/31/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

Bill Shannon 01/31/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

Deepak Anupalli 01/31/2012

[jsr342-experts] Re: Transactional interceptors and exceptions

Werner Keil 01/23/2012
 
 
Close
loading
Please Confirm
Close