Spring @Transactional 和 Camel Transacted 之间的关系

Relation between Spring @Transactional and Camel Transacted

如果 camel DSL 被标记为 transacted(),那么我们真的需要在 Spring 服务方法中添加 @Transactional 注解吗?

我很想知道In and Out of Camel和Spring事务交互。

任何帮助将不胜感激。

TL;DR

不,一般来说你不需要注释任何方法@Transactional来使 Camel 交易工作

Camel 和 Spring TransactionManager 之间的主要交互是 Camel 将事务处理委托给 Spring txManager,如果它被配置为这样做的话。换句话说:如果 Spring txManager 可用,Camel 会使用它,但您也可以使用其他 txManager。

对于此委派,不需要 @Transactional 注释。相反,您必须配置 Spring txManager 并将 Camel 路由标记为 transacted().

说来话长

但是,您的问题为假设留下了空间。你要注解什么方法@Transactional?包含路由的方法?路由调用的托管 bean 的方法?一种完全独立于骆驼路线的方法?

一笔交易Camel route creates a transaction scope around the whole route (1) or more specific the unit of work

举个例子:一个路由从一个JMS队列中读取数据,转换数据并写入多个其他JMS队列。如果您将路由标记为已处理并且在发送最后一条消息时发生错误,则事务将回滚并且不会发送任何消息。

由于事务作用域,在事务成功完成之前不会提交已经 "sent"(传出)的消息。回滚后,相同的消息(传入)由代理重新传递并由路由再次处理。

请注意,Camel 路线 可以 在路线中没有 transacted() 标记 (2) 的情况下进行交易。

但是,由于 Camel 是关于集成的,因此您经常 "mixed environments",例如 JMS 到数据库。或者更糟的是,您在路由期间执行 HTTP 请求。如果稍后发生错误,您将无法 "undo" 这些调用。

因此,在Camel的世界里,交易可以提供很多帮助,但往往是不够的。您必须实施补偿 才能真正回滚中止的路由处理。

如果你使用事务路由,一定要写Route tests who 模拟路由处理中的错误,并检查回滚是否按你预期的那样工作。

好吧,这些是关于 Camel 和交易的一些高级想法。如果您想更深入地研究,请获取我在评论中推荐的 Camel 书 :-)

脚注:

(1) 当路由包含有状态组件或 EIP(例如 aggregator, resequencer 等)时,它们会在 Camel 路由内引入事务边界。在这种情况下,事务范围结束于第一个有状态组件。因此,这些组件通常提供可选的持久性以提供保存状态的可能性。

为了使这种事务边界明确,我通常不会在这样的组件之后继续在同一路由中,而是创建一个新的并将有状态组件的结果消息发送到新路由。

(2) 例如,使用 JMS 本地事务的 JMS 消费者。