首页 > 解决方案 > Spring @Transactional 和 Camel Transacted 之间的关系

问题描述

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

我真的很想知道 Camel 和 Spring Transaction 的 In 和 Out 的交互。

任何帮助将不胜感激。

标签: apache-camelspring-transactionsspring-camel

解决方案


TL;博士

不,通常您不需要注释任何方法@Transactional来使 Camel 事务工作

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

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

漫长的故事

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

事务处理的Camel 路由围绕整个路由 (1) 或更具体的工作单元创建事务范围。

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

由于事务范围,在事务成功完成之前不会提交已经“发送”(传出)的消息。回滚后,相同的消息(传入)由代理重新传递并由路由再次处理。

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

但是,由于 Camel 是关于集成的,因此您经常有“混合环境”,例如 JMS 到数据库。或者更糟糕的是,您在路由期间执行 HTTP 请求。如果稍后发生错误,您将无法“撤消”这些调用。

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

如果您使用事务处理路由,请务必编写路由测试来模拟路由处理中的错误并检查回滚是否按预期工作。

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

脚注:

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

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

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


推荐阅读