简体   繁体   English

basicAck不会从代理中删除消息 - RabbitMQ

[英]basicAck does not remove message from broker - RabbitMQ

I'm doing following flow in my application: 我在我的应用程序中执行以下操作:

  1. get 1 message from broker(manual acknowledge) 从经纪人那里得到1条消息(手动确认)

  2. do some processing 做一些处理

  3. start transaction on database and broker 在数据库和代理上启动事务

  4. insert some records in database and publish some messages on broker(different queue) 在数据库中插入一些记录并在代理上发布一些消息(不同的队列)

  5. commit database and broker 提交数据库和代理

  6. ack message that you got from broker in step 1. 您在步骤1中从经纪人处获得的确认消息。

All operation on broker is done via a single channel. 经纪人的所有操作都是通过单一渠道完成的。 here is the preparation code: 这是准备代码:

Connection brokerConnection = factory.newConnection();              
Channel channel = brokerConnection.createChannel();
channel.basicQos(1);
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume("receive-queue", false, consumer);

Following is my code. 以下是我的代码。 I have removed try , catch parts to make it clear. 我已经删除了trycatch部分以使其清楚。 I log all exceptions to file. 我将所有例外记录到文件中。 Step 1: 步骤1:

QueueingConsumer.Delivery delivery = consumer.nextDelivery();
Request request = (Request) SerializationUtils.deserialize(delivery.getBody());

Step 2, 3, 4, 5: 第2,3,4,5步:

dbConnection.setAutoCommit(false);
channel.txSelect();

stmt = dbConnection.prepareStatement(query);
/* set paramteres */
stmt.executeUpdate();
channel.basicPublish(/* exchange name */, "KEY", MessageProperties.PERSISTENT_BASIC, /* result */ result);

dbConnection.commit();
channel.txCommit();
dbConnection.setAutoCommit(true);

Step 6: 第6步:

channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);

After one iteration I can see records in database and broker(means it is working fine until step 5). 在一次迭代之后,我可以在数据库和代理中看到记录(意味着它在第5步之前正常工作)。 The problem is the message on receive queue is not removed after step 6 and management plug-in shows one un-acked message. 问题是在步骤6之后未删除接收队列上的消息,并且管理插件显示一条未确认的消息。 Also I don't see any exception in log file. 此外,我在日志文件中看不到任何异常。 Can anyone help? 有人可以帮忙吗?

[UPDATE1] [UPDATE1]

Now I create one channel for publishing and another channel for receiving. 现在我创建一个用于发布的频道和另一个用于接收的频道。 This is working now. 现在正在运作。 So how to use a single channel for receiving and publishing(with transactions)? 那么如何使用单一渠道进行接收和发布(使用交易)? I have used a single channel for receiving and publishing before but that was without transactions. 我之前使用过单个频道进行接收和发布,但没有交易。

[UPDATE2] [UPDATE2]

I moved step 6 inside transaction and it is working now. 我在事务中移动了第6步,它现在正在运行。

dbConnection.setAutoCommit(false);
channel.txSelect();

stmt = dbConnection.prepareStatement(query);
/* set paramteres */
stmt.executeUpdate();
channel.basicPublish(/* exchange name */, "KEY", MessageProperties.PERSISTENT_BASIC, /* result */ result);

channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); 

dbConnection.commit();
channel.txCommit();
dbConnection.setAutoCommit(true);

I'm a bit confused. 我有点困惑。 I just want the publish section to be inside transaction. 我只是希望发布部分在内部事务中。

You've put the channel in transactional mode - and acks are transactional things. 您已将频道置于事务模式 - 而ack是事务性事物。 So you either need to consume and ack on a separate non-transactional channel, or else just accept that your ack needs to come before the tx.commit. 所以你需要在一个单独的非交易渠道上消费和确认,或者只是接受你的ack需要在tx.commit之前。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 RabbitMQ中不同线程中的basicGet和basicAck - basicGet and basicAck in different threads in RabbitMQ 如何强制RabbitMQ代理NACK消息进行测试? - How can I force a RabbitMQ broker to NACK a message for testing? 在集群环境中使用外部消息代理(RabbitMQ)将Spring套接字转换并发送给用户 - spring socket convertandsendtouser with external message broker(RabbitMQ) in cluster environment RabbitMQ BasicAck 在控制台上提供通道关闭错误消息 - Spring AMQP - RabbitMQ BasicAck giving channel shutdown error messages on console - Spring AMQP 将消息从本地经纪人传递到不连贯的中央经纪人 - Deliver message from a local broker to a disconected central broker Rabbitmq,接收来自客户端的消息 - Rabbitmq, receive message from client RabbitMQ嵌入式代理不是从Spring Boot应用程序启动的 - RabbitMQ embedded broker is not starting from spring boot application 通过RabbitMQ通过ID获取消息 - Get message by id from RabbitMQ 从kafka中的副本中删除无效的经纪人信息 - Remove invalid broker Information from Replicas in kafka 使用Spring AMQP时,如何正确处理RabbitMQ通道上basicAck的IOException? - How to properly handle IOException for basicAck on RabbitMQ Channel when using Spring AMQP?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM