9.2. 通过事务端点划分
如果路由开始时的消费者端点访问资源,则 transacted() 命令就不使用,因为它在轮询交换后发起事务。换句话说,交易开始过晚,将消费者端点包含在事务范围内。在这种情况下,正确的方法是使端点本身负责发起事务。能够管理事务的端点称为 事务端点。
事务端点划分有两种不同的模型,如下所示:
通常,事务端点会按以下方式分离事务:
- 当交换到达端点时,或者当端点成功轮询交换时,端点会调用其关联的事务管理器以开始事务。
- 端点将新事务附加到当前线程。
- 当交换达到路由结束时,事务端点会调用事务管理器提交当前的事务。
- 带有 InOut 交换的 JMS 端点 - 当 JMS 消费者端点接收 InOut 交换时,该交换将路由到另一个 JMS 端点,则必须被视为特殊情况。问题是,如果尝试在单个事务中包括整个请求/回复,则路由可能会死锁。
9.2.1. 带有 JMS 端点的路由示例 复制链接链接已复制到粘贴板!
第 9.2 节 “通过事务端点划分” 显示了一个路由示例,它通过路由开头的事务端点(在 from() 命令中)存在事务端点进行事务。所有路由节点都包含在事务范围内。在本例中,路由中的所有端点都访问 JMS 资源。
9.2.2. Java DSL 中的路由定义 复制链接链接已复制到粘贴板!
以下 Java DSL 示例演示了如何通过启动事务端点的路由来定义事务路由:
from("jmstx:queue:giro")
.to("jmstx:queue:credits")
.to("jmstx:queue:debits");
在前面的示例中,事务范围包含端点、jmstx:queue:giro、jmstx:queue:credits 和 jmstx:queue:debits。如果事务成功,则从 giro 队列永久移除交换,并推送到 信 队列和 debits 队列。如果事务失败,则交易不会转向贡献度和分 位 队列,并将交换重新推送到 giro 队列。默认情况下,JMS 会自动尝试重新传送消息。JMS 组件 bean 和 jmstx 必须明确配置为使用事务,如下所示:
<blueprint ...>
<bean id="jmstx" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration" ref="jmsConfig" />
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="transactionManager" ref="jmsTransactionManager" />
<property name="transacted" value="true" />
</bean>
...
</blueprint>
在上例中,transaction manager 实例( jmsTransactionManager )与 JMS 组件关联,而 transacted 属性设为 true,以启用对 InOnly 交换的事务解包。
9.2.3. Blueprint XML 中的路由定义 复制链接链接已复制到粘贴板!
前面的路由可以等效在 Blueprint XML 中,如下所示:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route>
<from uri="jmstx:queue:giro" />
<to uri="jmstx:queue:credits" />
<to uri="jmstx:queue:debits" />
</route>
</camelContext>
</blueprint>
9.2.4. DSL 翻译() 命令不需要 复制链接链接已复制到粘贴板!
在以事务性端点开头的路由中不需要 transacted() DSL 命令。然而,假设默认事务策略是 PROPAGATION_REQUIRED (请参阅 第 9.4 节 “事务传播策略”),通常会损害包含 transacted() 命令,如下例所示:
from("jmstx:queue:giro")
.transacted()
.to("jmstx:queue:credits")
.to("jmstx:queue:debits");
但是,此路由可能会以意外的方式工作,例如,如果一个 TransactedPolicy 有一个有非默认传播策略在 Blueprint XML 中创建。请参阅 第 9.1.4 节 “默认事务管理器和转换策略”。因此,通常最好不要将 transacted() DSL 命令包含在开头事务端点的路由中。
9.2.5. 路由开始时的事务端点 复制链接链接已复制到粘贴板!
以下 Apache Camel 组件在路由开始时显示为事务端点(例如,如果它们出现在 from() DSL 命令中)。也就是说,这些端点可以配置为作为事务客户端的行为,也可以访问事务的资源。
- ActiveMQ
- AMQP
- JavaSpace
- JMS
- JPA