Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JTA container managed transaction rollback not working for jaxrs endpoint

Rest Endpoint

<jaxrs:server id="jaxrs" 
              address="http://127.0.0.1:8080/jaxrs">

    <jaxrs:serviceBeans>
        <ref component-id="service1" />
        ...
        ...
        <ref component-id="serviceX" />
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <ref component-id="runtimeExceptionMapper" />
    </jaxrs:providers>
</jaxrs:server>

Route

<route id="secureBridgeRoute">
    <from uri="jetty:https://0.0.0.0:443/jaxrs?sslContextParametersRef=sslContextParameters&amp;matchOnUriPrefix=true&amp;minThreads=8&amp;maxThreads=16" />
    <transacted ref="JTA_TRANSACTION" />
    <to uri="jetty:http://127.0.0.1:8080/jaxrs?bridgeEndpoint=true&amp;throwExceptionOnFailure=true" />
</route>

DAO

<bean id="dao1" class="com.example.Dao1" activation="eager">
    <jpa:context unitname="PU" property="entityManager" type="TRANSACTION" />
</bean>

Service bean

<bean id="service1" class="com.example.Service1" activation="eager">
    <property name="dao1" ref="dao1" />
    <property name="dao2" ref="dao2" />
    <tx:transaction method="*" value="Required" />
</bean>

Service bean method pseudocode

boolean create(entity1, entity2) {
    dao1.persist(entity1);
    dao2.persist(entity2);
}

When dao2 persist failed, the transaction did not get rolled back. Entity1 is inserted into the DB.

Additional information

1) TransactionManager definition

<reference id="platformTransactionManager" interface="org.springframework.transaction.PlatformTransactionManager" />
<bean id="JTA_TRANSACTION" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
    <property name="transactionManager" ref="platformTransactionManager" />
    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" />
</bean>

2) My persistent unit is of type JTA and hibernate as the provider.

3) I have an ExceptionMapper, which when I look into it, the stacktrace shows the transaction indeed is marked for rollback.

4) The service beans are not separated to another bundle.

5) Hibernate autocommit is NOT true.

I am wondering if:

  1. CXF OutFaultInterceptor has "eaten" the exception that is supposed to be caught by the container for transaction rollback. As a result, the rollback did not occur.

  2. The Entity Manager has to be the same instance shared amongst all DAOs for the rollback to happen.

  3. Could it be that I need to separate the service into another bundle?

Appreciate if someone could let me know the correct approach on transaction handling at service layer for cxf jaxrs endpoint.

like image 517
allancth Avatar asked May 03 '16 06:05

allancth


1 Answers

The original data source is declared in a blueprint bundle, which is using commons-dbcp2. Finally, I got this working using pax-jdbc-pool-dbcp version 0.8.0.

Reference: https://ops4j1.jira.com/wiki/display/PAXJDBC/Pooling+and+XA+support+for+DataSourceFactory

Thanks Christian Schneider for the hint.

like image 75
allancth Avatar answered Sep 22 '22 04:09

allancth