9.4. 事务传播策略


如果要影响事务客户端创建新事务的方式,您可以使用 JmsTransactionManager 并为其指定事务策略。特别是 Spring transaction 策略,您可以指定事务的传播行为。例如,如果事务客户端要创建新事务,并且它检测到该事务已与当前线程关联,是否应该会失败并创建新的事务,并挂起旧的事务?或者说是否让现有事务接管?通过在事务策略中指定传播行为来监管这些行为。

事务策略在 Blueprint XML 中实例化。然后,您可以通过提供 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 ID。请参阅 第 9.4.3 节 “在 Blueprint XML 中定义策略 Bean”

9.4.1. 关于 Spring 事务策略

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

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

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

<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. 传播行为的描述

Spring 支持以下传播行为。这些值最初基于 JavaeEE 支持的传播行为:

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

如果当前事务存在,则在嵌套的事务中执行,其他行为与 PROPAGATION_REQUIRED 类似。

注意

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

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

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

注意

此策略要求当前事务被暂停,这是所有事务管理器不支持的功能。

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

创建一个新事务,挂起当前事务(如果存在)。

注意

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

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

9.4.3. 在 Blueprint 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");

使用这种方法时,PR OPAGATION_NEVER 策略不可避免地中止每个事务,从而导致事务回滚。您应该能轻松查看这对应用程序的影响。

注意

请记住,传递到 transacted() 的字符串值是一个 bean ID,而不是传播行为名称。在本例中,将选择 bean ID 与传播行为名称相同,但这不是必须的。例如,如果您的应用程序使用多个事务管理器,您可能会遇到多个具有特定传播行为的策略。在这种情况下,您不能在传播行为后直接命名 Bean。

9.4.5. 蓝图 XML 中的 PROPAGATION_N EVER 策略示例

以上路由可以在 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.