-
Bug
-
Resolution: Not a Bug
-
Major
-
fuse-7.11.1-GA
-
None
-
False
-
None
-
False
-
%
-
-
Todo
-
-
-
Very Likely
Under the spring boot runtime, the camel-jpa JpaTransactionManager does not work as expected with mixed transaction and rollback scenario.
camel-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <bean class="sample.MyCarProcessor" id="myCarProcessor"/> <bean class="sample.MyBicyclePrcessor" id="myBicycleProcessor"/> <bean class="org.apache.camel.spring.spi.SpringTransactionPolicy" id="PROPAGATION_REQUIRES_NEW"> <property name="transactionManager" ref="transactionManager"/> <property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/> </bean> <bean class="org.apache.camel.spring.spi.SpringTransactionPolicy" id="PROPAGATION_MANDATORY"> <property name="transactionManager" ref="transactionManager"/> <property name="propagationBehaviorName" value="PROPAGATION_MANDATORY"/> </bean> <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route id="parent-route"> <from id="route-timer" uri="timer:foo?repeatCount=1"/> <transacted id="transactionA"/> <log id="_log1" message=">>> call rollback-route"/> <to id="_to1" uri="direct:rollback"/> <log id="_log2" message=">>> call commit-route"/> <to id="_to2" uri="direct:commit"/> <log id="_log3" message="done"/> </route> <route id="rollback-route"> <from id="_from1" uri="direct:rollback"/> <onException id="_onException1"> <exception>java.lang.Exception</exception> <log id="_log4" message=">>> rollback-route's' onException block. mark rollback"/> <rollback id="rollbackA" markRollbackOnlyLast="true"/> </onException> <transacted id="transactionB" ref="PROPAGATION_MANDATORY"/> <process id="_process1" ref="myCarProcessor"/> <to id="_to3" uri="jpa:io.fabric8.quickstarts.camel.Car?usePersist=true"/> <throwException exceptionType="java.lang.IllegalArgumentException" id="_throwException1" message="Forced"/> </route> <route id="commit-route"> <from id="_from2" uri="direct:commit"/> <onException id="_onException2"> <exception>java.lang.Exception</exception> <log id="_log5" message=">>> commit-route's onException block"/> </onException> <transacted id="transactionC" ref="PROPAGATION_REQUIRES_NEW"/> <process id="_process2" ref="myBicycleProcessor"/> <to id="_to4" uri="jpa:io.fabric8.quickstarts.camel.Bicycle?usePersist=true"/> </route> </camelContext> </beans>
Following query is used to create a test DB.
CREATE DATABASE sample; create table car ( id integer, name varchar(10) ); create table bicycle ( id integer, name varchar(10) );
log
09:28:59.345 [main] INFO i.f.quickstarts.camel.Application - Started Application in 5.082 seconds (JVM running for 5.464) 09:29:00.409 [Camel (MyCamel) thread #1 - timer://foo] INFO parent-route - >>> call rollback-route Hibernate: insert into car (name, id) values (?, ?) 09:29:00.446 [Camel (MyCamel) thread #1 - timer://foo] INFO rollback-route - >>> rollback-route's' onException block. mark rollback 09:29:00.448 [Camel (MyCamel) thread #1 - timer://foo] WARN o.a.c.processor.DefaultErrorHandler - Rollback (MessageId: ID-fedora-1703636938098-0-2 on ExchangeId: ID-fedora-1703636938098-0-1) due: Forced Message History --------------------------------------------------------------------------------------------------------------------------------------- RouteId ProcessorId Processor Elapsed (ms) [parent-route ] [parent-route ] [timer://foo?repeatCount=1 ] [ 105] [parent-route ] [transactionA ] [transacted ] [ 0] [parent-route ] [_log1 ] [log ] [ 0] [parent-route ] [_to1 ] [direct:rollback ] [ 0] [rollback-route ] [transactionB ] [transacted[ref:PROPAGATION_MANDATORY] ] [ 0] [rollback-route ] [_process1 ] [ref:myCarProcessor ] [ 0] [rollback-route ] [_to3 ] [jpa:io.fabric8.quickstarts.camel.Car?usePersist=true ] [ 33] [rollback-route ] [_throwException1 ] [throwException[ref:null] ] [ 0] [rollback-route ] [_log4 ] [log ] [ 0] [rollback-route ] [rollbackA ] [rollback ] [ 0] 09:29:00.449 [Camel (MyCamel) thread #1 - timer://foo] WARN o.a.c.s.spi.TransactionErrorHandler - Transaction rollback (0x5f1eff72) redelivered(false) for (MessageId: ID-fedora-1703636938098-0-2 on ExchangeId: ID-fedora-1703636938098-0-1) caught: java.lang.IllegalArgumentException: Forced 09:29:00.449 [Camel (MyCamel) thread #1 - timer://foo] INFO parent-route - >>> call commit-route Hibernate: insert into bicycle (name, id) values (?, ?) 09:29:00.458 [Camel (MyCamel) thread #1 - timer://foo] INFO parent-route - done 09:29:00.461 [Camel (MyCamel) thread #1 - timer://foo] WARN o.a.c.s.spi.TransactionErrorHandler - Transaction rollback (0xbaf87a5) redelivered(false) for (MessageId: ID-fedora-1703636938098-0-2 on ExchangeId: ID-fedora-1703636938098-0-1) caught: Transaction silently rolled back because it has been marked as rollback-only 09:29:00.463 [Camel (MyCamel) thread #1 - timer://foo] WARN o.a.c.component.timer.TimerConsumer - Error processing exchange. Exchange[ID-fedora-1703636938098-0-1]. Caused by: [org.springframework.transaction.UnexpectedRollbackException - Transaction silently rolled back because it has been marked as rollback-only] org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:752) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:152) at org.apache.camel.spring.spi.TransactionErrorHandler.doInTransactionTemplate(TransactionErrorHandler.java:182) at org.apache.camel.spring.spi.TransactionErrorHandler.processInTransaction(TransactionErrorHandler.java:140) at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:107) at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:116) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201) at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:197) at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:79) at java.base/java.util.TimerThread.mainLoop(Timer.java:566) at java.base/java.util.TimerThread.run(Timer.java:516)
It looks like if the current Transaction is a parent transaction and camel rollback component is executed, all of the transactions which includes "PROPAGATION_REQUIRES_NEW" will rollback. That is not expected.