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

时间:2013-08-15 06:47:48

标签: java rabbitmq amqp

我正在我的应用程序中执行以下操作:

  1. 从经纪人处获得1条消息(手动确认)

  2. 做一些处理

  3. 在数据库和代理上启动事务

  4. 在数据库中插入一些记录并发布一些消息     经纪人(不同的队列)

  5. 提交数据库和代理

  6. 您在步骤1中从经纪人处获得的确认消息。

  7. 经纪人的所有操作都是通过单一渠道完成的。这是准备代码:

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

    以下是我的代码。我已移除trycatch部分以明确说明。我将所有例外记录到文件中。 第1步:

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

    步骤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);
    

    第6步:

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

    经过一次迭代,我可以在数据库和代理中看到记录(意味着它在第5步之前正常工作)。问题是在步骤6之后未删除接收队列上的消息,并且管理插件显示一条未确认的消息。此外,我在日志文件中看不到任何异常。有人可以帮忙吗?

    [UPDATE1]

    现在我创建了一个用于发布的频道和另一个用于接收的频道。现在正在运作。那么如何使用单一渠道进行接收和发布(使用交易)?我之前使用过单个频道进行接收和发布,但没有交易。

    [UPDATE2]

    我在事务中移动了第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);
    

    我有点困惑。我只是希望发布部分在内部交易。

1 个答案:

答案 0 :(得分:6)

您已将频道置于事务模式 - 而ack是事务性事物。所以你需要在一个单独的非交易渠道上消费和确认,或者只是接受你的确认需要在tx.commit之前来。