geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Jencks <david_jen...@yahoo.com>
Subject Re: exposing exceptions that caused a rollback
Date Thu, 24 Feb 2011 03:56:33 GMT

On Feb 23, 2011, at 7:35 PM, Kevan Miller wrote:

> 
> On Feb 22, 2011, at 4:37 PM, David Jencks wrote:
> 
>> cf 
>> https://issues.apache.org/jira/browse/GERONIMO-4576 
>> https://issues.apache.org/jira/browse/OPENEJB-1091 
>> 
>> For a long time we've known of this problem where an exception thrown by a transaction
synchronization that causes a transaction to be marked for rollback only is lost.  When the
user or openejb tries to commit the transaction the transaction manager throws a RollbackException
which currently doesn't have any information about the original exception.
>> 
>> People have complained about this for a long time.... now we're trying to fix it.
>> 
>> There are two parts AFAICT.  I think in openejb we just need to take the TransactionRolledBackException
we are currently throwing and call initCause with the RollbackException from the tm.  In TransactionPolicy
this would be something like
>> 
>>       } catch (RollbackException e) {
>> 
>>           txLogger.info("The transaction has been rolled back rather than commited:
" + e.getMessage());
>>           // TODO can't set initCause on a TransactionRolledbackException, update
the convertException and related code to handle something else 
>>           Throwable txe = new javax.transaction.TransactionRolledbackException("Transaction
was rolled back, presumably because setRollbackOnly was called during a synchronization: "+e.getMessage());
>> --            throw new ApplicationException(txe);
>> ++            throw new ApplicationException(txe.initCause(e);
>> 
>> In the transaction implementation we need to keep track of the exception that caused
us to mark rollback only and then use it as the cause of the RollbackException, e.g.
>> 
>> private Exception markRollbackCause;
>> 
>> ...
>> RollbackException rollbackException = new RollbackException("Unable to commit: transaction
marked for rollback");
>> if (markRollbackCause != null) { 
>> rollbackException.initCause(markRollbackCause); 
>> }
>> throw rollbackException; 
>> 
>> ...
>> 
>>   private void markRollbackCause(Exception e) {
>>       if (markRollbackCause == null) {
>>           markRollbackCause = e;
>>       }
>>   }
>> 
>> (this tm code is committed in rev 1073479 in my sandbox tm)
>> 
>> At the moment if a sync throws an exception, we keep calling the other syncs, and
it would be possible for other ways of marking rollback only due to an exception to occur
more than once as well.  So there's a question as to whether we should only record the first
cause of rollback only or if we should keep track of a list of causes.  The code above only
tracks the first  cause.  I'm really not sure what to think about this and would appreciate
comments.
>> 
>> Thoughts?
> 
> Great to get more data captured. So, I'm all for it... 
> 
> Personally, I would think the *first* cause will almost always be the most important
information a user would want... Any situations where subsequent exceptions are going to yield
valuable information? Or will they mostly generate noise?

Well, since the known cause of this problem is openjpa flushes during the tx syncs, it would
be entirely possible to have more than one if there is more than one persistence unit/persistence
context involved in the transaction. So I'd guess it's quite uncommon but entirely possible.
 It's probably only an hour or so more work to implement something for more exception, dunno
how much testing we'd want to do.

I don't know if there are likely to be additional "side effect" exceptions caused by a particular
exception.  Offhand I can't think of any.

thanks
david jencks
 
> 
> --kevan


Mime
View raw message