9.4. 事务传播策略


如果要影响事务客户端创建新事务的方式,您可以使用 JmsTransactionManager 并为它指定一个事务策略。特别是,Spring 事务策略允许您为事务指定传播行为。例如,如果事务客户端是创建新的事务,它检测到已与当前线程关联的事务,如果它继续并创建新的事务,请暂停旧的事务?或者应该让现有交易接管?通过指定事务策略上的传播行为,可以控制这些类型的行为。

事务策略在蓝图 XML 中作为 Bean 进行实例化。然后,您可以通过将其 bean ID 作为 transacted () DSL 命令的参数来引用事务策略。例如,如果要启动受行为的事务( PROPAGATION_REQUIRES_NEW ),您可以使用以下路由:

from("file:src/data?noop=true")
        .transacted("PROPAGATION_REQUIRES_NEW")
        .bean("accountService","credit")
        .bean("accountService","debit")
        .to("file:target/messages");

其中 PROPAGATION_REQUIRES_NEW 参数指定使用 PROPAGATION_REQUIRES_NEW 行为配置的事务策略 bean 的 bean ID。请参阅 第 9.4.3 节 “在蓝图 XML 中定义策略 Bean”

9.4.1. 关于 Spring 事务策略

Apache Camel 可让您使用 org.apache.camel.spring.spi.SpringTransactionPolicy 类来定义 Spring 事务策略,这基本上是一个围绕原生 Spring 类的打包程序。SpringTransactionPolicy 类封装了两部分数据:

  • PlatformTransactionManager 类型的事务管理器的引用
  • 传播行为

例如,您可以使用 PROPAGATION_MANDATORY 行为实例化 Spring 事务策略 bean,如下所示:

<blueprint ...>
  <bean id="PROPAGATION_MANDATORY "class="org.apache.camel.spring.spi.SpringTransactionPolicy">
    <property name="transactionManager" ref="txManager" />
    <property name="propagationBehaviorName" value="PROPAGATION_MANDATORY" />
  </bean>
  ...
</blueprint>

9.4.2. propagation 行为的描述

Spring 支持以下传播行为。这些值最初在 JavaeEE 支持的传播行为上建模:

PROPAGATION_MANDATORY
支持当前的事务。如果没有当前事务,则抛出异常。
PROPAGATION_NESTED

如果存在当前的事务,请在嵌套的事务中执行,否则行为类似于 PROPAGATION_REQUIRED

注意

所有事务管理器都不支持嵌套事务。

PROPAGATION_NEVER
不支持当前的事务。如果当前事务存在,则抛出异常。
PROPAGATION_NOT_SUPPORTED

不支持当前的事务。始终以非事务方式执行。

注意

此策略需要暂停当前的事务,此功能不受所有事务管理器的支持。

PROPAGATION_REQUIRED
(默认)支持当前事务。如果不存在,则创建一个新名称。
PROPAGATION_REQUIRES_NEW

创建新的事务,并暂停当前事务(如果存在)。

注意

所有事务管理器都不支持挂起事务。

PROPAGATION_SUPPORTS
支持当前的事务。如果不存在,则以非事务方式执行。

9.4.3. 在蓝图 XML 中定义策略 Bean

以下示例演示了如何为所有支持的传播行为定义事务策略 Bean。为方便起见,每个 bean ID 与传播行为值的指定的值匹配,但实践中,您可以使用您要用于 bean ID 的任何值。

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <bean id="PROPAGATION_MANDATORY " class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="txManager" />
        <property name="propagationBehaviorName" value="PROPAGATION_MANDATORY" />
    </bean>

    <bean id="PROPAGATION_NESTED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="txManager" />
        <property name="propagationBehaviorName" value="PROPAGATION_NESTED" />
    </bean>

    <bean id="PROPAGATION_NEVER" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="txManager" />
        <property name="propagationBehaviorName" value="PROPAGATION_NEVER" />
    </bean>

    <bean id="PROPAGATION_NOT_SUPPORTED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="txManager" />
        <property name="propagationBehaviorName" value="PROPAGATION_NOT_SUPPORTED" />
    </bean>

    <!-- This is the default behavior. -->
    <bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="txManager" />
    </bean>

    <bean id="PROPAGATION_REQUIRES_NEW" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="txManager" />
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW" />
    </bean>

    <bean id="PROPAGATION_SUPPORTS" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="txManager" />
        <property name="propagationBehaviorName" value="PROPAGATION_SUPPORTS" />
    </bean>

</blueprint>
注意

如果要将任何这些 bean 定义粘贴到您自己的蓝图 XML 配置中,请记得自定义对事务管理器的引用。也就是说,将对 txManager 的引用替换为您的事务管理器 bean 的实际 ID

9.4.4. Java DSL 中带有 PROPAGATION_NEVER 策略的示例路由

演示该事务策略对事务有一些影响的简单方式是将 PROPAGATION_NEVER 策略插入到现有事务的中间,如以下路由所示:

from("file:src/data?noop=true")
        .transacted()
        .bean("accountService","credit")
        .transacted("PROPAGATION_NEVER")
        .bean("accountService","debit");

以这种方式使用,PROPAGATION_NEVER 策略可避免中止每个事务,从而导致回滚。您应该能轻松查看对应用的影响。

注意

请记住,传递给 transacted () 的字符串值是一个 bean ID,而不是传播行为名称。在本例中,选择 bean ID 与传播行为名称相同,但这并非总是如此。例如,如果您的应用程序使用多个事务管理器,则最终可能会有多个具有特定传播行为的策略 Bean。在这种情况下,您无法在传播行为后简单地命名 Bean。

9.4.5. 蓝图 XML 中带有 PROPAGATION_NEVER 策略的路由示例

前面的路由可以在 Blueprint XML 中定义,如下所示:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <camelContext xmlns="http://camel.apache.org/schema/blueprint">
        <route>
            <from uri="file:src/data?noop=true" />
            <transacted />
            <bean ref="accountService" method="credit" />
            <transacted ref="PROPAGATION_NEVER" />
            <bean ref="accountService" method="debit" />
        </route>
    </camelContext>

</blueprint>
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.