Spring @Transactional 和 Camel Transacted 之间的关系

Raj*_*har 1 apache-camel spring-transactions spring-camel

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

我真的很想知道Camel和Spring Transaction交互的进出。

任何帮助将不胜感激。

bur*_*rki 5

长话短说

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

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

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

故事很长

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

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

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

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

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

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

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

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

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

脚注:

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

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

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