在 Apache Camel 2.20.2 中,我创建了一个带有 split() 和 recipientlist() 的路由。我希望每个 Exchange 的整个路由和收件人都发生在同一个事务中。我对 Camel 何时使用单独的线程和事务边界感到困惑。我已经阅读了 Camel 文档并梳理了网络上的各种文章/论坛。我正在寻找一个确定的答案。
在骆驼我有这条路线:
from("seda:process")
.transacted("TRANS_REQUIRESNEW")
.to("sql:classpath:sql/SelForUpdate.sql?dataSource=DataSource1")
.split(body())
.shareUnitOfWork()
.setHeader("transactionId", simple("${body.transactionId}"))
// Datasource 2 updates happening using "direct:xxxx" recipients
.recipientList().method(Routing.class).shareUnitOfWork().end()
.to("sql:classpath:sql/UpdateDateProcessed.sql?dataSource=DataSource1");
在 Spring 上下文中,我定义了事务管理:
<jee:jndi-lookup expected-type="javax.sql.DataSource" id="Datasource1" jndi-name="jdbc/Datasource1"/>
<jee:jndi-lookup expected-type="javax.sql.DataSource" id="Datasource2" jndi-name="jdbc/Datasource2"/>
<bean id="datasource1TxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="Datasource1" />
</bean>
<bean id="datasource2TxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="Datasource2" />
</bean>
<bean id="TRANS_REQUIRESNEW"
class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager">
<bean id="txMgrRouting"
class="org.springframework.data.transaction.ChainedTransactionManager">
<constructor-arg>
<list>
<ref bean="datasource1TxManager" />
<ref bean="datasource2TxManager" />
</list>
</constructor-arg>
</bean>
</property>
<property name="propagationBehaviorName"
value="PROPAGATION_REQUIRES_NEW" />
</bean>
当我运行该路线时,似乎对 Datasource1 和 Datasource2 的更新发生在单独的事务中。此外,Datasource1 的 SelForUpdate.sql 和 UpdateDateProcessed.sql 似乎发生在单独的事务中。
我的问题是,这段代码中创建的新线程在哪里,事务边界在哪里?我将如何在一个事务上下文中发生这种情况?
在阅读 Apache Camel Developer's Cookbook 时,我了解 Split 和 RecipientList 模式都使用相同的线程进行所有处理(除非使用并行处理)。使用我创建的 SpringTransactionPolicy bean,似乎所有工作都在此路由中,并且接收者路由应该发生在相同的事务上下文中。我对么?