Atomikos Forum

Using Transaction which is STATUS_MARKED_ROLLBACK

Hello,
Testcase is i am having an outer service calling an inner Service. Container is Spring and both called methods are advised to run in the same transaction. In the testcase i set in the inner service rollbackOnly. Back on the outer service i want to do some searching using the already STATUS_MARKED_ROLLBACK transaction. Which gives the following exception. I know that i cant undo the rollbackonly, and every data i change from then would not persist. But it might still be useful to work on the datasources, if just to search for some data to put into my service response. Why is that behaviour not permitted?

Atomikos Version: 3.7.0

22:27:07,404 ERROR Run:138 - org.hibernate.exception.GenericJDBCException: could not execute query
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute query
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:255)
    at at.itsv.playground.deployable.jta.Service.searchUsersOnDataSourceOne(Service.java:148)
    at at.itsv.playground.deployable.jta.Service.doInsert(Service.java:132)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at at.itsv.playground.deployable.jta.advice.LocalRollbackOnlyHelperAdvice.invoke(LocalRollbackOnlyHelperAdvice.java:17)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy16.doInsert(Unknown Source)
    at at.itsv.playground.container.Run.main(Run.java:136)
Caused by: org.hibernate.exception.GenericJDBCException: could not execute query
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.loader.Loader.doList(Loader.java:2536)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    at org.hibernate.loader.Loader.list(Loader.java:2271)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452)
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:246)
    ... 18 more
Caused by: com.atomikos.jdbc.AtomikosSQLException: Transaction is marked for rollback only or has timed out
    at com.atomikos.jdbc.AtomikosSQLException.throwAtomikosSQLException(AtomikosSQLException.java:44)
    at com.atomikos.jdbc.AtomikosConnectionProxy.enlist(AtomikosConnectionProxy.java:214)
    at com.atomikos.jdbc.AtomikosConnectionProxy.invoke(AtomikosConnectionProxy.java:138)
    at $Proxy9.prepareStatement(Unknown Source)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:534)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:452)
    at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:161)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1700)
    at org.hibernate.loader.Loader.doQuery(Loader.java:801)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.doList(Loader.java:2533)
    ... 26 more
Caused by: com.atomikos.datasource.xa.session.InvalidSessionHandleStateException: Transaction is marked for rollback only or has timed out
    at com.atomikos.datasource.xa.session.NotInBranchStateHandler.checkEnlistBeforeUse(NotInBranchStateHandler.java:59)
    at com.atomikos.datasource.xa.session.TransactionContext.checkEnlistBeforeUse(TransactionContext.java:85)
    at com.atomikos.datasource.xa.session.SessionHandleState.notifyBeforeUse(SessionHandleState.java:176)
    at com.atomikos.jdbc.AtomikosConnectionProxy.enlist(AtomikosConnectionProxy.java:204)
    ... 35 more
Jörg Maurer Send private email
Monday, July 11, 2011
 
 
Hi,

Disallowing this is the simplest and easiest thing that works. I see two good reasons for this behavior:

1. Our code/design is simpler
2. Anything you read would by definition be uncommitted data that you return to the client (which is dangerous IMHO)

Your thoughts?
Guy Pardon Send private email
Wednesday, July 13, 2011
 
 
Hello Guy,

Had a quick look at jta spec, its predecessor corba and other transaction products.

Quoting "https://issues.jboss.org/browse/JBTM-664"#3rd comment
"A transaction is still logically active if in the rollback-only state. That status does not signify that the transaction has begun to terminate. If you assume that STATUS_MARKED_ROLLBACK makes the transaction inactive then by that logic it should be illegal to call setRollbackOnly multiple times (it should throw IllegalStateException subsequently). In fact that isn't the case and as long as the transaction has not terminated, or begun to terminate, it's correct to allow that to be called multiple times. A transaction is considered inactive once it begins the two-phase commit protocol (commit is called) or is rolled back."

Quoting "http://documentation.progress.com/output/Iona/orbix/gen3/33/html/orbixots33_pguide/CosTransactions_cl.html"#Current::rollback_only()
Calling Current::rollback() rolls back the transaction immediately, preventing unnecessary work from being done between the time the transaction is marked for rollback and the time the transaction is actually rolled back.

The as-is situation in atomikos is that STATUS_MARKED_ROLLBACK and STATUS_ROLLBACK are now equal in effect regarding to the business service code.
1) Feels like what was not intended in the jta-spec(yes, it is said that this spec is fuzzy), as there are two different status.
2) has serious business service coding implications. I am forced to guard my code against that situation and that exception.

Your argument #1, this a question of spec and - if not clearly stated - by common understanding. Understood e.g. like working with jboss and glassfish - are you in need to guard against that situation?

Your argument #2, yes, but such a fact must be known to technical staff, should be decided by business experts and must be possible to opt either way for the service implementation.

BTW, The same situation with quite a different effect is happening in spring :) Here spring people thought they will do the developer any good throwing an UnexpectedRollbackException if the outest service code does not acknowledge a rollback. Forcing implementors to call setRollbackOnly on their own wrapper around trasaction management. Hm, was really unexpected, not only to me...
Jörg Maurer Send private email
Wednesday, July 13, 2011
 
 
Hi again,

Thanks for the input; I have created a feature request for this - not yet prioritized in the backlog.

BTW we _do_ allow calling setRollbackOnly twice or more...
Guy Pardon Send private email
Monday, July 25, 2011
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics