Uploaded image for project: 'Red Hat Fuse'
  1. Red Hat Fuse
  2. ENTESB-22499

sub-transaction with spring JpaTransactionManager does not work as expected

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not a Bug
    • Icon: Major Major
    • fuse-7.13-GA
    • fuse-7.11.1-GA
    • Camel
    • 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.

              Unassigned Unassigned
              rhn-support-hfuruich Hisao Furuichi
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: