首先肯定的是,rabbitmq的事务是比较消耗rabbitmq的性能的,使用事务会降低大约2~10倍的消息吞吐量,还会使生产者应用程序产生同步。如果在整个业务代码执行过程中,有发布消息的操作,那么业务代码任何一步发生异常的时候,都会触发rabbitmq的回滚事务操作,那么原本应该被发布到队列中的消息因为回滚都不会被提交到队列中,同时数据的数据也会因为捕获到异常发生回滚,从而保证了业务数据的一致性。
以下代码为生产端的关于开启事务的代码:
public static void sendMsg() throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.12.12");
Connection connection = factory.newConnection();
//创建一条信道
Channel channel = connection.createChannel();
//声明交换机
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
//声明队列
String queueName = "transactionQueueJll";
channel.queueDeclare(queueName, false, false, false, null);
//routingKey绑定队列到交换机
String routingKey = "errorJll";
channel.queueBind(queueName, TransactionProducer.EXCHANGE_NAME, routingKey);
// 将当前信道设置成事务模式
channel.txSelect();
for (int i = 0; i < 10; i++) {
//可以看成是业务数据
String message = "业务数据 " + i;
try {
channel.basicPublish(EXCHANGE_NAME, routingKey, false, null, message.getBytes());
log.info("### send message, routingKey: {}, message: {}", routingKey, message);
//可以认为是修改数据库中的操作异常
int n = 10 / 0;
// 提交事务
channel.txCommit();
} catch (Exception e) {
e.printStackTrace();
// 回滚事务
channel.txRollback();
//还可以添加数据库的事务回滚
}
}
channel.close();
connection.close();
}