当前位置: 首页 > 知识库问答 >
问题:

多线程中的Spring AMQP事务

轩辕阳焱
2023-03-14

我正在使用Spring AMQP(RabbitMQ实现),我试图将单个事务传播到多个线程中。

例如,假设有3个队列,名称为X、Y、Z,首先我使用thread-1从队列X获取一条消息,然后,该消息被提供给thread-0,thread-0中的消息被克隆并通过thread-3发送到队列Y、thread-2和队列Z。线程0等待线程3和线程4的完成,以提交或回滚消息。注意,这里我使用了4个线程。

我想要的基本上是将这3个操作(获取消息并将其放入两个队列)作为单个事务处理。i、 e.如果我成功地将消息发送到队列Y,但未能将其发送到Z,则发送到Y的消息将被回滚,原始消息也将回滚到队列X。

到目前为止,我已经设法通过threadLocals(主要是TransactionStatus和TransactionSynchronizationManager.resources)获取事务信息,并且我能够将这3个操作绑定到一个事务中。

但我的问题是向原始队列X发送ACK/NACK,即使我提交/回滚事务,它也只适用于队列Y和Z。从X获取的消息始终处于未确认状态。

我有一个频道。basicAck(),兔子。提交必要的()方法,但没有成功。

请注意,我也启用了ChannelTransaction。非常感谢您的帮助。

共有1个答案

任飞鸣
2023-03-14

Spring事务绑定到单个线程。您可以直接使用RabbitMQ客户机使其工作,但您必须在所有线程之间共享同一个通道。然而,RabbitMQ文档强烈建议不要这样做:

通道实例不能在线程之间共享。应用程序应该更喜欢每个线程使用一个通道,而不是跨多个线程共享同一个通道。虽然通道上的某些操作可以安全地同时调用,但有些操作则不安全,并且会导致不正确的帧交错。。。

在任何情况下,即使您在单个线程上进行工作,RabbitMQ事务也相当弱,不能保证有多大的安全性;参见代理语义。

AMQP仅在事务涉及单个队列时保证原子性,即tx中的所有发布都被路由到单个队列,并且所有ACK都与来自同一队列的消息相关。。。

 类似资料:
  • Spring Transaction不支持多线程,所以我尝试在thread的run()方法中手动管理事务。但是,没用! 我想在下面的示例中回滚每个线程的run()方法,当其中有异常抛出时。(在以下情况下,插入到UNKNOWN_TABLE) 我的预期结果是“开始,1,3,5,结束”。 而实际结果是‘开始,1,2,3,4,5,结束’。 欢迎任何回复!谢谢! 主要类别: 服务等级:

  • 我需要执行父任务,父任务可能有子任务,也可能没有子任务。每个父任务和子任务都应该在线程中运行。如果父任务或子任务执行中出现错误,则必须回滚父任务和子任务的事务。我正在使用hibernate4。

  • 一、 我与CachingConnectionFactory有一个SpringAMQP项目。我需要从AMQP连接获取一些属性,例如:状态、连接时间、通道和一些运行时度量。CachingConnectionFactory是否有任何指标支持(例如:https://www.rabbitmq.com/blog/2016/11/30/metrics-support-in-rabbitmq-java-clien

  • 问题内容: 我有如下方法: methodB可以正常工作吗?根据我的理解,methodB将附加methodA的事务,如果methodA在methodB之前退出该怎么办?我想事务只能提交methodA。但是methodB将不会提交,因为该事务之前已提交。 我可以对方法B使用@Transactional(propagation = Propagation.REQUIRES_NEW)。这可以使method

  • 问题内容: 我正在使用Callable接口在serviceImpl中编写多线程程序。我正在使用spring事务管理器。在DB中执行更新操作时,它会成功执行。但是更新后的数据不会反映在DB中。但是,当我运行不带多线程的程序时,它将在DB中更新。 这是我的配置 我可以转向事务管理器的另一种方法。只是我想确认这种方法是否支持多线程。所以我的问题是 spring事务管理器是否支持多线程(我的意思是仅通过声