9.2. 通过事务端点划分


如果路由开始时的消费者端点访问资源,则 transacted() 命令就不使用,因为它在轮询交换后发起事务。换句话说,交易开始过晚,将消费者端点包含在事务范围内。在这种情况下,正确的方法是使端点本身负责发起事务。能够管理事务的端点称为 事务端点

Camel 路由 tx 端点

事务端点划分有两种不同的模型,如下所示:

  • 通常,事务端点会按以下方式分离事务:

    1. 当交换到达端点时,或者当端点成功轮询交换时,端点会调用其关联的事务管理器以开始事务。
    2. 端点将新事务附加到当前线程。
    3. 当交换达到路由结束时,事务端点会调用事务管理器提交当前的事务。
  • 带有 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:girojmstx:queue:creditsjmstx: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
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2026 Red Hat
返回顶部