使用Spring的Camel Transactional客户端,如何回滚路由更改?

时间:2014-07-30 05:39:32

标签: spring transactions apache-camel

考虑以下两个测试。 findOne()没有副作用,delete()对底层的h2数据库有副作用。我的问题是@Transactional没有回滚delete()方法的更改。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:app-context.xml")
public class AccountProcessorTest extends BaseRouteTest {

      private static final String ACCOUNTS_ENDPOINT = "seda:bar";

      @Test
      @Transactional
      public void findOne() {

          final Map<String, Object> headers = new HashMap<String, Object>();
          headers.put("id", 1);
          headers.put(Exchange.HTTP_METHOD, "GET");

          final String response = template.requestBodyAndHeaders(ACCOUNTS_ENDPOINT, null, headers, String.class);
          assertEquals("Checking account",JsonPath.read(response, "name"));

      }

     @Test
     @Transactional
     public void delete() {

         final Map<String, Object> headers = new HashMap<String, Object>();
         headers.put("id", 1);
         headers.put(Exchange.HTTP_METHOD, "DELETE");

         final String response = template.requestBodyAndHeaders(ACCOUNTS_ENDPOINT, null, headers, String.class);
         assertEquals(200, JsonPath.read(response, "code"));

      }

 }

BaseRouteTest只是一个实用工具,我获得了对Camel ProducerTemplate的引用

public class BaseRouteTest implements InitializingBean {

   @Autowired
   private ApplicationContext applicationContext;

   protected ProducerTemplate template;

   @Override
   public void afterPropertiesSet() throws Exception {
      template = getCamelContext().createProducerTemplate();
   }

   private CamelContext getCamelContext() {
      return applicationContext.getBean("foo", CamelContext.class);
   }

}

我已使用交易标记将路线标记为交易。

<!-- camel-context -->
<camel:camelContext id="foo">
    <camel:route>
        <camel:from uri="seda:bar"/>
        <camel:transacted />
        <camel:process ref="accountProcessor"/>
    </camel:route>
</camel:camelContext>

我的弹簧配置文件:

<context:component-scan base-package="com.backbase.progfun"/>

<!-- embedded datasource -->
<jdbc:embedded-database id="dataSource" type="H2">
    <jdbc:script location="classpath:data/schema.ddl"/>
    <jdbc:script location="classpath:data/insert.sql"/>
</jdbc:embedded-database>

<!-- spring jdbc template -->
<bean class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg ref="dataSource" />
</bean>

<!-- transaction management start -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!-- transaction management end -->

<!-- camel-context -->
<camel:camelContext id="foo">
    <camel:route>
        <camel:from uri="seda:bar"/>
        <camel:transacted />
        <camel:process ref="accountProcessor"/>
    </camel:route>
</camel:camelContext>

如果你克隆我在这里找到的github repo,你可以快速尝试一下: https://github.com/altfatterz/camel-transaction

如果运行AccountProcessorTest,则findOne()测试用例会失败,因为delete()测试用例的副作用不会回滚。

任何建议都将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:0)

交易不在SEDA队列中传输。

因此,您的测试启动的交易与您的路线中的交易不同。因此,当您的测试启动的事务被回滚时,您的路由所做的更改将不会回滚。