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");
from("file:src/data?noop=true")
.transacted("PROPAGATION_REQUIRES_NEW")
.bean("accountService","credit")
.bean("accountService","debit")
.to("file:target/messages");
其中 参数指定使用 PROPAGATION_REQUIRES_NEW 行为的事务策略的 bean PROPAGATION_REQUIRES_NEW 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 策略,如下所示:
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 的任何值。
如果要将任何 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");
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 中定义,如下所示: