rabbitmq 手动提交_RabbitMQ事务性消息和确认模式

本文详细介绍了RabbitMQ中确保消息完整性的两种策略:事务机制和确认模式。事务通过txSelect()启动,txCommit()提交或txRollback()回滚,确保消息发送成功。确认模式包括普通确认、批量确认和异步监听确认,通过confirmSelect()开启,配合waitForConfirms()或addConfirmListener()监听消息发送状态。确认模式比事务更快,但对消费者影响不同,手动确认的消费者必须ack后再提交事务,否则消息不会从队列中移除。
摘要由CSDN通过智能技术生成

事务消息与数据库的事务类似,只是MQ的消息是要保证消息是否会全部发送成功,防止消息丢失的一种策略。

RabbitMQ有两种策略来解决这个问题:

1.通过AMQP的事务机制实现

2.使用发送者确认模式实现

1.事务

事务的实现主要是对信道(Channel)的设置,主要方法如下:

1. channel.txSelect()  声明启动事务模式

2.channel.txCommit() 提交事务

3.channel.txRollback()回滚事务

1.事务性消息发送

开启事务之后必须手动channel.txCommit();提交或者channel.txRollback();回滚。

packagerabbitmq;importcom.rabbitmq.client.Channel;importcom.rabbitmq.client.Connection;importcom.rabbitmq.client.ConnectionFactory;public classProducer {public static Connection getConnection() throwsException {//创建连接工程,下面给出的是默认的case

ConnectionFactory factory = newConnectionFactory();

factory.setHost("192.168.99.100");

factory.setPort(5672);

factory.setUsername("guest");

factory.setPassword("guest");

factory.setVirtualHost("/");returnfactory.newConnection();

}public static voidmain(String[] args) {

Connection connection= null;

Channel channel= null;try{

connection=getConnection();

channel=connection.createChannel();/*** 声明一个队列。

* 参数一:队列名称

* 参数二:是否持久化

* 参数三:是否排外 如果排外则这个队列只允许有一个消费者

* 参数四:是否自动删除队列,如果为true表示没有消息也没有消费者连接自动删除队列

* 参数五:队列的附加属性

* 注意:

* 1.声明队列时,如果已经存在则放弃声明,如果不存在则会声明一个新队列;

* 2.队列名可以任意取值,但需要与消息接收者一致。

* 3.下面的代码可有可无,一定在发送消息前确认队列名称已经存在RabbitMQ中,否则消息会发送失败。*/channel.queueDeclare("myQueue", true, false, false,null);//启动事务,必须用txCommit()或者txRollback()回滚

channel.txSelect();//假设这里处理业务逻辑

String message = "hello,message!";/*** 发送消息到MQ

* 参数一:交换机名称,为""表示不用交换机

* 参数二:为队列名称或者routingKey.当指定了交换机就是routingKey

* 参数三:消息的属性信息

* 参数四:消息内容的字节数组*/channel.basicPublish("", "myQueue", null, message.getBytes());//提交事务

channel.txCommit();

}catch(Exception e) {

e.printStackTrace();

}finally{try{if (channel != null) {//回滚。如果未异常会提交事务,此时回滚无影响

channel.txRollback();

channel.close();

}if (connection != null) {

connection.close();

}

}catch(Exception ignore) {//ignore

}

}

}

}

测试可以注释掉提交事务的代码发现mq不会新增消息。

2.消费者事务测试

经测试,自动确认模式下。即使事务不提交,也会读取到消息并从队列移除。也就是暂时得出的结论是事务对消费者无效。

packagerabbitmq;importjava.io.IOException;importjava.util.concurrent.TimeoutException;importcom.rabbitmq.client.Channel;importcom.rabbitmq.client.Connection;importcom.rabbitmq.client.ConnectionFactory;importcom.rabbitmq.client.DefaultConsumer;importcom.rabbitmq.client.Envelope;importcom.rabbitmq.client.AMQP.BasicProperties;public classConsumer {public staticConnectionFactory getConnectionFactory() {//创建连接工程,下面给出的是默认的case

ConnectionFactory factory = newConnectionFactory();

factory.setHost("192.168.99.100");

factory.setPort(5672);

factory.setUsername("guest");

factory.setPassword("guest");

factory.setVirtualHost("/");returnfactory;

}public static void main(String[] args) throwsIOException, TimeoutException {

ConnectionFactory connectionFactory=getConnectionFactory();

Connection newConnection= null;

Channel createChannel= null;try{

newConnection=connectionFactory.newConnection();

createChannel=newConnection.createChannel();/*** 声明一个队列。

* 参数一:队列名称

* 参数二:是否持久化

* 参数三:是否排外 如果排外则这个队列只允许有一个消费者

* 参数四:是否自动删除队列,如果为true表示没有消息也没有消费者连接自动删除队列

* 参数五:队列的附加属性

* 注意:

* 1.声明队列时,如果已经存在则放弃声明,如果不存在则会声明一个新队列;

* 2.队列名可以任意取值,但需要与消息接收者一致。

* 3.下面的代码可有可无,一定在发送消息前确认队列名称已经存在RabbitMQ中,否则消息会发送失败。*/createChannel.queueDeclare("myQueue", true, false, false,null);/*** 开启事务

* 消费者开启事务后,即使不提交也会获取到消息并且从队列删除。

* 结论:

* 事务对消费者没有任何影响*/createChannel.txSelect();/*** 接收消息。会持续坚挺,不能关闭channel和Connection

* 参数一:队列名称

* 参数二:消息是否自动确认,true表示自动确认接收完消息以后会自动将消息从队列移除。否则需要手动ack消息

* 参数三:消息接收者的标签,用于多个消费者同时监听一个队列时用于确认不同消费者。

* 参数四:消息接收者*/createChannel.basicConsume("myQueue", true, "", newDefaultConsumer(createChannel) {

@Overridepublic voidhandleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,byte[] body) throwsIOException {

String string= new String(body, "UTF-8");

System.out.println("接收到d消息: -》 " +string);

}

});

}catch(Exception e) {

e.printStackTrace();

}finally{

}

}

}

上面是自动确认模式的消费者,不受事务的影响。

如果是手动确认消息的消费者,在开启事务下,必须手动commit,否则不会移除消息。

如下:手动确认模式+事务的用法

packagerabbitmq;importjava.io.IOException;import

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值