aries-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christian Schneider <ch...@die-schneider.net>
Subject Re: XAJpaTemplate#txExpr call results in commit attempt after Exception is thrown. Bug?
Date Mon, 15 Feb 2016 09:42:13 GMT
Hi Matthew,

thanks for looking into this.

I also found some other strange behaviour when trying to fix this issue
https://issues.apache.org/jira/browse/ARIES-1494

I built a test case that opens a Coordination early to achieve a long 
lived EntityManager then calls a method annotated with @Transactional to 
write data.
Interestingly the data did not seem to have been written after the 
transaction.

In one circumstance I also had the exception.
javax.persistence.TransactionRequiredException: no transaction is in 
progress

     @Transactional
     public void addCar(Car car) {
         em.persist(car);
         em.flush();
     }

The exception happens at flush. If I remove "em.flush" it works but the 
entity does not seem to be written.

Interestingly this only happens since I added this code to the 
JpaInterceptor to fix the issue above:
             try {
                 if (isInJtaTransaction()) {
                     em.joinTransaction();
                 }
             } catch (RuntimeException e) {
                 LOG.warn("Exception while joining trasnaction.", e);
             }
Not sure what exactly happens there but there seem to be some deeper 
issue in the code.

Christian


On 12.02.2016 15:14, Matthew.W.Pitts@wellsfargo.com wrote:
> Ok, I have more info on my problem... I have rebuilt jpa-support with a little
> more logging and a couple of checks before commit to test that the transaction
> status is not STATUS_NO_TRANSACTION. So, I'm now seeing what I think is the
> original exception that started this flow and here is what I think is
> happening.
>
> 1. Commit attempt is made from XAJpaTemplate#safeFinish during txExpr
> 2. Eclipselink performs commit attempt
> 3. Eclipselink throws OptimisticLockException due to legitimate condition
> 4. ??Eclipselink then goes ahead and marks the TX for rollback on its own??
> (not sure on this one, but I think it's key to the rest of my logic)
> 5. The TX manager then checks tx status for rollback and propagates a
> RollbackException with cause of the original OptimisticLockException indicated
> by [1]. Eclipselink must be calling setRollbackOnly(Throwable reason) somehow.
> 6. RollbackException is caught and wrapped in a RuntimeException by
> #wrapThrowable from call in XAJpaTemplate#safeFinish
> 7. The now-propagating RuntimeException is caught in XAJpaTemplate#txExpr and
> rollback logic is performed via safeRollback
> 8. Rollback logic attempts to set rollback on the TX which now results in
> STATUS_NO_TRANSACTION indicated by [2] (I think somehow rollback() was already
> invoked on the TX manager and so the thread is no longer associated with a TX)
> 9. #safeRollback simply catches and logs exceptions during rollback and still
> attempts to call #safeFinish
> 10. This then results in another rollback attempt in
> TransactionAttribute.REQUIRED#finish
> 11. I think there's at least another cycle of some of this logic due to
> #safeRollback always calling #safeFinish
> 12. A whole lot of logs/traces are generated for this one, rather benign,
> OptimisticLockException
>
> The docs for TransactionManager#rollback states that "When this method
> completes, the thread is no longer associated with a transaction." So I'm
> assuming that it is somehow being called from TransactionAttribute#finish and
> then other things are attempted which is why I'm seeing these
> STATUS_NO_TRANSACTION exceptions.
>
> So, here's what I'm thinking.... either the rollback logic should test the TX
> status before doing so; or there should be special handling for the
> RollbackException as it indicates a pretty specific situation. Perhaps
> #safeFinish could just catch RollbackExceptions and rethrow them? Then the
> catch code in #txExpr could simply catch RollbackExceptions and do nothing
> more than rewrap via wrapThrowable?
>
> This is a mess of thoughts in my head now, so hopefully this came out
> rational.
>
> TIA
> -matt
>
>
> [1]
> Caused by: javax.transaction.RollbackException: Unable to commit: transaction
> marked for rollback
> 	at
> org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:272)
> ~[na:na]
> 	at
> org.apache.geronimo.transaction.manager.TransactionManagerImpl.commit(TransactionManagerImpl.java:252)
> ~[na:na]
> 	at
> org.apache.aries.jpa.support.xa.impl.TransactionAttribute$4.finish(TransactionAttribute.java:105)
> ~[na:na]
> 	at
> org.apache.aries.jpa.support.impl.XAJpaTemplate.safeFinish(XAJpaTemplate.java:81)
> ~[na:na]
> 	... 11 common frames omitted
>
>
> [2]
> 2016-02-12 11:21:31,615 WARN SomeThread [o.a.a.j.s.i.XAJpaTemplate] Exception
> during transaction rollback
> java.lang.IllegalStateException: Cannot set rollback only, status is
> STATUS_NO_TRANSACTION
> 	at
> org.apache.geronimo.transaction.manager.TransactionImpl.setRollbackOnly(TransactionImpl.java:141)
> ~[na:na]
> 	at
> org.apache.geronimo.transaction.manager.TransactionImpl.setRollbackOnly(TransactionImpl.java:126)
> ~[na:na]
> 	at
> org.apache.aries.jpa.support.impl.XAJpaTemplate.safeRollback(XAJpaTemplate.java:96)
> [org.apache.aries.jpa.support-2.3.0.jar:na]
> 	at
> org.apache.aries.jpa.support.impl.XAJpaTemplate.txExpr(XAJpaTemplate.java:65)
> [org.apache.aries.jpa.support-2.3.0.jar:na]
>
>
>
> -----Original Message-----
> From: Matthew.W.Pitts@wellsfargo.com [mailto:Matthew.W.Pitts@wellsfargo.com]
> Sent: Thursday, February 11, 2016 11:53 AM
> To: dev@aries.apache.org
> Subject: RE: XAJpaTemplate#txExpr call results in commit attempt after
> Exception is thrown. Bug?
>
> Christian, Thank you very much for the explanation. It certainly makes sense
> to me to follow with the conventions set by EJB/Spring here.
>
> I'm not too concerned with controlling rollback logic at this point as much as
> I am wondering why I even end up with this no-transaction exception after the
> initial exception. I'm assuming that somehow the call to
> TransactionAttribute#begin is failing and so a transaction is never truly
> started for the thread. Do you know if a test in
> TransactionAttribute.REQUIRED#finish for man.getStatus() would result in
> STATUS_NO_TRANSACTION in the call-stack I'm experiencing? If so, perhaps that
> method should test for that before calling commit to protect situations like
> this?
>
> I'm seeing this stacktrace from more than one place that's using the
> JpaTemplate API and much of this code is exactly the same as it was with the
> 2.2 bundle versions and I never saw this problem.
>
> Thanks again,
> -matt
>
> -----Original Message-----
> From: Christian Schneider [mailto:cschneider111@gmail.com] On Behalf Of
> Christian Schneider
> Sent: Thursday, February 11, 2016 11:09 AM
> To: dev@aries.apache.org
> Subject: Re: XAJpaTemplate#txExpr call results in commit attempt after
> Exception is thrown. Bug?
>
> Hi Matthew,
>
> I am also not sure how to handle the exceptions.
> The idea about the current code is that you might have a service
> interface that defines its own exceptions that do not necessarily mean a
> rollback is necessary.
> A bit like the default in spring.
> https://www.catalysts.cc/wissenswertes/spring-transactional-rollback-on-checked-exceptions/
> The problem though is that we currently can not customize the exceptions
> to rollback on.
>
> So I am not sure if this is rather a bug or a change request but the
> need for it is quite clear.
> So feel free to open an issue.
>
> One thing we could do is change the default to roll back on all
> exceptions. Another thing would be to allow to specify which exceptions
> to roll back on. The reason why I did not yet
> add this is that it makes the interface of JPATemplate a lot more
> complicated. This is a bit bad as you have to implement or mock the
> interface to write unit tests.
>
> I am also careful about changing interfaces as we need to support them
> long term.
> Do you have a good idea how the interface of JPATemplate should handle this?
>
> Ideally I would like to use the @Transactional annotation for the
> JPATemplate case too. It would allow to specify which exceptions to
> rollback on. I am not sure if it can be used in this way though. At
> least I found no good way to use it. Since I think Java 7 it seems to be
> possible to also have annotations on types. So maybe we could do
> something like:
> @Reference(target = "(osgi.unit.name=tasklist)")
> @RollbackOn(Exception.class)
> JPATemplate jpaTemplate;
>
> Christian
>
>
> On 11.02.2016 16:06, Matthew.W.Pitts@wellsfargo.com wrote:
>> [1] seems to be happening now after upgrading the latest Aries JPA 2.3.0
>> bundles available on maven. [2] shows my aries bundle list.
>>
>> It appears that when the safeRollback call propagates down to the #finish
>> call
>> in TransactionAttribute.REQUIRED that the call to
>> TransactionManager#getStatus
>> does *not* indicate rollback and so a commit attempt is performed.
>> XAJpaTemplate appears to only set rollback if the exception that occurred
>> during the TX is either a RuntimeException or Error due to the logic in
>> XAJpaTemplate#shouldRollback. But if another type of Exception is
>> propagating
>> then TransactionAttribute.REQUIRED#finish is going to try to commit because
>> the TX hasn't been marked for rollback.
>>
>> I would think that any Throwable type should result in a rollback - not just
>> RuntimeExceptions and Errors. Perhaps XAJpaTemplate#shouldRollback should
>> just
>> return true?
>>
>> Does this make sense? Is this a bug?
>>
>> I'm also not sure why the commit call results in the exception shown - I
>> guess
>> somehow the thread-local transaction is lost due to the original exception.
>> So
>> I'm wondering if XAJpaTemplate#safeRollback should log the incoming
>> exception
>> to assist in the event the original exception is suppressed.
>>
>> Any assistance is greatly appreciated.
>>
>> -Matthew Pitts
>>
>> [1]
>> java.lang.IllegalStateException: No transaction associated with current
>> thread
>>           at
>> org.apache.geronimo.transaction.manager.TransactionManagerImpl.commit(TransactionManagerImpl.java:249)
>>           at
>> org.apache.aries.jpa.support.xa.impl.TransactionAttribute$4.finish(TransactionAttribute.java:105)
>>           at
>> org.apache.aries.jpa.support.impl.XAJpaTemplate.safeFinish(XAJpaTemplate.java:81)
>>           at
>> org.apache.aries.jpa.support.impl.XAJpaTemplate.safeRollback(XAJpaTemplate.java:101)
>>           at
>> org.apache.aries.jpa.support.impl.XAJpaTemplate.txExpr(XAJpaTemplate.java:65)
>>           at
>> com.wellsfargo.nss.osgi.persistence.tx.impl.JpaTemplateTxContext.txExpr(JpaTemplateTxContext.java:30)
>>           at
>> com.wellsfargo.nss.osgi.persistence.tx.impl.AbstractTxContext.tx(AbstractTxContext.java:19)
>>
>> [2]
>> g! lb aries
>> START LEVEL 100
>>      ID|State      |Level|Name
>>      53|Active     |   50|Apache Aries JPA Container adapter for EclipseLink
>> (2.3.0)
>>      59|Active     |   50|Apache Aries JPA container (2.3.0)
>>      63|Active     |   50|Apache Aries JPA support (2.3.0)
>>      64|Active     |   50|Apache Aries Transaction Enlisting JDBC Datasource
>> (2.1.2.SNAPSHOT)
>>      66|Active     |   50|Apache Aries Transaction Manager (1.3.1.SNAPSHOT)
>>      70|Active     |   50|Apache Aries Transaction Blueprint (2.1.0)
>>      71|Active     |   50|Apache Aries JPA Container API (2.3.0)
>>     114|Active     |   20|Apache Aries Blueprint CM (1.0.7)
>>     121|Active     |   20|Apache Aries Blueprint API (1.0.1)
>>     123|Active     |   20|Guava: Google Core Libraries for Java (15.0.0)
>>     125|Active     |   20|Guava: Google Core Libraries for Java (18.0.0)
>>     129|Active     |   20|Apache Aries Proxy Bundle (1.0.0)
>>     133|Active     |   20|Apache Aries JNDI Support for Legacy Runtimes
>> (1.0.0)
>>     136|Installed  |   20|Apache Aries Web Url handler (1.0.0)
>>     143|Active     |   20|Apache Aries Blueprint Core (1.4.4)
>>     151|Active     |   20|Apache Aries JNDI Core (1.0.2)
>>     155|Active     |   20|Apache Aries JNDI API (1.1.0)
>>     158|Active     |   20|Apache Aries JNDI URL Handler (1.1.0)
>>     162|Active     |   20|Apache Aries Util (1.1.0)
>> g!
>>
>>
>>
>>
>


-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com


Mime
View raw message