JtaTransactionManager kein rollback nach gescheiterter Begehen, während "Spülen"


Update: ich testete es mit Bitronix TM und es rollbacks perfekt, so dass die Frage, JBoss TM (arjuna) oder an meiner Konfiguration.

Update 2: wie Es aussieht Transaktionen sind nicht global, ich habe versucht, verschiedene Datenquellen, Bitronix datasource hat allowLocalTransactions Eigenschaft und nach Einstellung meiner Anwendung eine Ausnahme auslöst, die etwas versucht, es im lokalen Modus. Wenn ich Bitronix mit dieser datasource es funktioniert ohne Fehler. Ich glaube, es ist etwas falsch in configs.

Ich habe ein Problem mit JTA-Transaktionen. Ich bin mit Tomcat 7 + Hibernate 4 + Feder 3 + JBoss TS 4 und JTA-Transaktionen.

Nehme an, es ist die folgende Methode:

@Transactional(propagation = Propagation.REQUIRED)
public void testMethod() {
    insertOfSomeNewEntityInstance();
    updateOfAnotherEntity();
}

private void insertOfSomeNewEntityInstance() {
    SomeEntity entity = new SomeEntity();
    someEntityDAO.save(entity);
}

private void updateOfAnotherEntity() {
    AnotherEntity anotherEntity = anotherEntityDAO.findBySomeProperty(1L);
    anotherEntity.incrementSomeValue();
    anotherEntityDAO.save(anotherEntity);
}

Wenn diese Methode wirft "org.hibernate.StaleObjectStateException: Zeile wurde aktualisiert oder gelöscht, die von einer anderen Transaktion (oder unsaved-value mapping war falsch)" während "updateOfAnotherEntity()" Methode der Ausführung oder andere runtime-Ausnahme, die passieren könnte, während "Spülen" (Ruhezustand zeigt auch: HHH000346: Fehler bei der managed flush [Zeile wurde aktualisiert oder gelöscht, die von einer anderen Transaktion (oder unsaved-value mapping war falsch).
dann das Ergebnis insertOfSomeNewEntityInstance() die Ausführung wird nicht zurückgesetzt.

Nach dem Debuggen dieses Problems fand ich "doCommit" - Methode in org.springframework.die Transaktion.jta.JtaTransaction Manager

@Override
    protected void doCommit(DefaultTransactionStatus status) {
        JtaTransactionObject txObject = (JtaTransactionObject) status.getTransaction();
        try {
            int jtaStatus = txObject.getUserTransaction().getStatus();
            if (jtaStatus == Status.STATUS_NO_TRANSACTION) {
                throw new UnexpectedRollbackException("JTA transaction already completed - probably rolled back");
            }
            if (jtaStatus == Status.STATUS_ROLLEDBACK) {
                try {
                    txObject.getUserTransaction().rollback();
                }
                catch (IllegalStateException ex) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Rollback failure with transaction already marked as rolled back: " + ex);
                    }
                }
                throw new UnexpectedRollbackException("JTA transaction already rolled back (probably due to a timeout)");
            }
            txObject.getUserTransaction().commit();
        }
        catch (RollbackException ex) {
            throw new UnexpectedRollbackException(
                    "JTA transaction unexpectedly rolled back (maybe due to a timeout)", ex);
        }
        catch (HeuristicMixedException ex) {
            throw new HeuristicCompletionException(HeuristicCompletionException.STATE_MIXED, ex);
        }
        catch (HeuristicRollbackException ex) {
            throw new HeuristicCompletionException(HeuristicCompletionException.STATE_ROLLED_BACK, ex);
        }
        catch (IllegalStateException ex) {
            throw new TransactionSystemException("Unexpected internal transaction state", ex);
        }
        catch (SystemException ex) {
            throw new TransactionSystemException("JTA failure on commit", ex);
        }
    }

Wenn "txObject.getUserTransaction().commit();" schlägt mit RollbackException dann wirft diese Methode UnexpectedRollbackException und hier ist der Teil von org.springframework.die Transaktion.Unterstützung.AbstractPl atformTransactionManager processCommit (...), fängt es:

}
 catch (UnexpectedRollbackException ex) {
                //can only be caused by doCommit
                triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
                throw ex;
    }

Sehe ich keine rollbacks in triggerAfterCompletion () - Methode und nach dieser Methode alles bereinigt Ressourcen.

Zusammenfassend, Frühjahr/jboss nur verpflichtet das Ergebnis insertOfSomeNewEntityInstance(), nicht ausgeführt werden, updateOfAnotherEntity (), weil die gleichzeitige Modifizierung der Fehler, und nicht rollback nichts. Wenn ich manuell werfen Laufzeit oder überprüft Ausnahme von updateOfAnotherEntity() es rollbacks richtig, das Problem tritt nur auf, wenn Hibernate wirft einige exception zur Laufzeit, während "Spülen".

überwintern.cfg

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
    <property name="dialect">${dialect}</property>
    <property name="max_fetch_depth">1</property>
    <property name="hibernate.jdbc.batch_size">25</property>
    <property name="show_sql">false</property>
    <property name="format_sql">false</property>
    <property name="use_sql_comments">false</property>
    <property name="hibernate.session_factory_name">TestSessionFactory</property>
    <property name="hibernate.session_factory_name_is_jndi">false</property>
    <property name="hibernate.current_session_context_class">jta</property>
    <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
    <property name="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform</property>
    <property name="hibernate.id.new_generator_mappings">true</property>
    <property name="hibernate.cache.infinispan.cfg">infinispan.xml</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.infinispan.InfinispanRegionFactory</property>
</session-factory>
</hibernate-configuration>

jbossts-properties.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <entry key="CoordinatorEnvironmentBean.commitOnePhase">YES</entry>
    <entry key="CoordinatorEnvironmentBean.defaultTimeout">300</entry>
    <entry key="ObjectStoreEnvironmentBean.transactionSync">ON</entry>
    <entry key="CoreEnvironmentBean.nodeIdentifier">1</entry>
    <entry key="JTAEnvironmentBean.xaRecoveryNodes">1</entry>
    <entry key="JTAEnvironmentBean.xaResourceOrphanFilterClassNames">
        com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter
        com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter
    </entry>

    <entry key="CoreEnvironmentBean.socketProcessIdPort">0</entry>

    <entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
        com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
        com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
        com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule
    </entry>

    <entry key="RecoveryEnvironmentBean.expiryScannerClassNames">
        com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
    </entry>

    <entry key="RecoveryEnvironmentBean.recoveryPort">4712</entry>

    <entry key="RecoveryEnvironmentBean.recoveryAddress"></entry>

    <entry key="RecoveryEnvironmentBean.transactionStatusManagerPort">0</entry>
    <entry key="RecoveryEnvironmentBean.transactionStatusManagerAddress"></entry>

    <entry key="RecoveryEnvironmentBean.recoveryListener">YES</entry>

</properties>

Teil applicationContext.xml

<bean class="com.arjuna.ats.jta.TransactionManager" factory-method="transactionManager" id="arjunaTransactionManager"></bean>
    <bean class="com.arjuna.ats.jta.UserTransaction" factory-method="userTransaction" id="arjunaUserTransaction"></bean>

    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
        <property name="transactionManager" ref="arjunaTransactionManager"/>
        <property name="userTransaction" ref="arjunaUserTransaction"/>
    </bean>

    <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.XADataSource" destroy-method="close">
        <property name="url" value="${database.url}" />
        <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
        <property name="username" value="${database.user}" />
        <property name="password" value="${database.password}" />
    </bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" destroy-method="destroy">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation"><value>classpath:hibernate.cfg.xml</value></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.cache.use_second_level_cache">false</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
            </props>
        </property>
    </bean>

    <tx:annotation-driven mode="proxy" proxy-target-class="false" transaction-manager="transactionManager"/>

Und log:

Completing transaction for [...testMethod]
Triggering beforeCommit synchronization
Triggering beforeCompletion synchronization
BaseTransaction.getStatus
TransactionImple.getStatus
Initiating transaction commit
BaseTransaction.getStatus
TransactionImple.getStatus
BaseTransaction.commit
TransactionImple.commitAndDisassociate
SynchronizationImple.beforeCompletion
BaseTransaction.getStatus
TransactionImple.getStatus

insert into .....
update ... set ...

BaseTransaction.setRollbackOnly
TransactionImple.setRollbackOnly
BasicAction::preventCommit( BasicAction: 0:ffffc0a800ab:8d15:51b6fe47:3 status: ActionStatus.RUNNING)
HHH000346: Error during managed flush [Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [...]]
ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple< 0:ffffc0a800ab:8d15:51b6fe47:4, org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization@76d7a0b8 >
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [...]
        at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2509) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3228) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3126) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3456) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:140) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:369) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:287) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:339) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:113) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:273) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:93) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:162) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1165) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:126) [narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1010) [spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) [spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) [spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:387) [spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) [spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) [spring-aop-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) [spring-aop-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at $Proxy126.testMethod(Unknown Source) [na:na]
        ...

BasicAction::preventCommit( BasicAction: 0:ffffc0a800ab:8d15:51b6fe47:3 status: ActionStatus.ABORT_ONLY)
BasicAction::Abort() for action-id 0:ffffc0a800ab:8d15:51b6fe47:3
SynchronizationImple.afterCompletion
TransactionImple.equals
SynchronizationImple.afterCompletion
BasicAction::removeChildThread () action 0:ffffc0a800ab:8d15:51b6fe47:3 removing TSThread:2
BasicAction::removeChildThread () action 0:ffffc0a800ab:8d15:51b6fe47:3 removing TSThread:2 result = true
TransactionReaper::remove ( BasicAction: 0:ffffc0a800ab:8d15:51b6fe47:3 status: ActionStatus.ABORTED )
Triggering afterCompletion synchronization
Clearing transaction synchronization
Exception
org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.
        at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1013) ~[spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) ~[spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) ~[spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:387) ~[spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) ~[spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) ~[spring-aop-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        at $Proxy126.testMethod(Unknown Source) ~[na:na]
        ...
Caused by: javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.
        at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1177) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:126) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1010) ~[spring-tx-3.1.4.RELEASE.jar:3.1.4.RELEASE]
        ... 32 common frames omitted
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [...]
        at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2509) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3228) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3126) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3456) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:140) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:369) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:287) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:339) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:113) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53) ~[hibernate-core-4.2.2.Final.jar:4.2.2.Final]
        at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:273) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:93) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:162) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1165) ~[narayana-jta-4.17.4.Final.jar:4.17.4.Final]
        ... 34 common frames omitted

InformationsquelleAutor Andriy Nastyn | 2013-06-11

Schreibe einen Kommentar