JTA 容器管理的事务回滚不适用于 jaxrs 端点
JTA container managed transaction rollback not working for jaxrs 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 id="secureBridgeRoute">
<from uri="jetty:https://0.0.0.0:443/jaxrs?sslContextParametersRef=sslContextParameters&matchOnUriPrefix=true&minThreads=8&maxThreads=16" />
<transacted ref="JTA_TRANSACTION" />
<to uri="jetty:http://127.0.0.1:8080/jaxrs?bridgeEndpoint=true&throwExceptionOnFailure=true" />
</route>
DAO
<bean id="dao1" class="com.example.Dao1" activation="eager">
<jpa:context unitname="PU" property="entityManager" type="TRANSACTION" />
</bean>
服务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>
服务bean方法伪代码
boolean create(entity1, entity2) {
dao1.persist(entity1);
dao2.persist(entity2);
}
当 dao2 persist 失败时,事务没有回滚。 Entity1 被插入到数据库中。
附加信息
1) 事务管理器定义
<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) 我的持久化单元是 JTA 类型,提供者是 hibernate。
3) 我有一个 ExceptionMapper,当我查看它时,堆栈跟踪显示事务确实被标记为回滚。
4) 服务 bean 没有被分离到另一个 bundle。
5) Hibernate 自动提交不正确。
我想知道是否:
CXF OutFaultInterceptor 有 "eaten" 应该被容器捕获以进行事务回滚的异常。结果没有回滚。
实体管理器必须是在所有 DAO 之间共享的同一个实例才能发生回滚。
难道我需要将服务拆分成另一个包?
如果有人能让我知道 cxf jaxrs 端点的服务层事务处理的正确方法,我将不胜感激。
原始数据源在使用commons-dbcp2 的蓝图包中声明。最后,我使用 pax-jdbc-pool-dbcp 版本 0.8.0.
完成了这项工作
参考:https://ops4j1.jira.com/wiki/display/PAXJDBC/Pooling+and+XA+support+for+DataSourceFactory
感谢 Christian Schneider 的提示。
休息端点
<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 id="secureBridgeRoute">
<from uri="jetty:https://0.0.0.0:443/jaxrs?sslContextParametersRef=sslContextParameters&matchOnUriPrefix=true&minThreads=8&maxThreads=16" />
<transacted ref="JTA_TRANSACTION" />
<to uri="jetty:http://127.0.0.1:8080/jaxrs?bridgeEndpoint=true&throwExceptionOnFailure=true" />
</route>
DAO
<bean id="dao1" class="com.example.Dao1" activation="eager">
<jpa:context unitname="PU" property="entityManager" type="TRANSACTION" />
</bean>
服务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>
服务bean方法伪代码
boolean create(entity1, entity2) {
dao1.persist(entity1);
dao2.persist(entity2);
}
当 dao2 persist 失败时,事务没有回滚。 Entity1 被插入到数据库中。
附加信息
1) 事务管理器定义
<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) 我的持久化单元是 JTA 类型,提供者是 hibernate。
3) 我有一个 ExceptionMapper,当我查看它时,堆栈跟踪显示事务确实被标记为回滚。
4) 服务 bean 没有被分离到另一个 bundle。
5) Hibernate 自动提交不正确。
我想知道是否:
CXF OutFaultInterceptor 有 "eaten" 应该被容器捕获以进行事务回滚的异常。结果没有回滚。
实体管理器必须是在所有 DAO 之间共享的同一个实例才能发生回滚。
难道我需要将服务拆分成另一个包?
如果有人能让我知道 cxf jaxrs 端点的服务层事务处理的正确方法,我将不胜感激。
原始数据源在使用commons-dbcp2 的蓝图包中声明。最后,我使用 pax-jdbc-pool-dbcp 版本 0.8.0.
完成了这项工作参考:https://ops4j1.jira.com/wiki/display/PAXJDBC/Pooling+and+XA+support+for+DataSourceFactory
感谢 Christian Schneider 的提示。