RabbitMQ 高级特性——事务

文章目录

前言

前面我们学习了 RabbitMQ 的延迟队列,通过延迟队列可以实现生产者生产的消息不是立即被消费者消费。那么这篇文章我们将来学习 RabbitMQ 的事务。

事务

RabbitMQ 是基于 AMQP 协议实现的,该协议实现了事务机制,因此 RabbitMQ 也支持事务机制。Spring AMQP 也提供了对事务相关的操作。RabbitMQ 事务允许开发者确保消息的发送和接收是原子性的,要么全部成功,要么全部失败。然而,需要明确的是,RabbitMQ 的事务支持主要集中在生产者(发送方)端,并且它可能不是处理高并发场景下的最佳实践,因为使用事务会增加消息发送的延迟和复杂性。

那么我们来看看在 Spring 中如何实现 RabbitMQ 事务。

先来看看在没有事务的情况下是否能够保证消息发送的原子性:

java 复制代码
public static final String TRANS_EXCHANGE = "trans.exchange";
public static final String TRANS_QUEUE = "trans.queue";

声明交换机、队列和绑定关系:

java 复制代码
@Configuration
public class TransConfig {
    @Bean("transExchange")
    public Exchange transExchange() {
        return ExchangeBuilder.directExchange(Constants.TRANS_EXCHANGE).build();
    }

    @Bean("transQueue")
    public Queue transQueue() {
        return QueueBuilder.durable(Constants.TRANS_QUEUE).build();
    }

    @Bean("transBinding")
    public Binding transBinding(@Qualifier("transExchange") Exchange exchange, @Qualifier("transQueue") Queue queue) {
        return BindingBuilder.bind(queue).to(exchange).with("trans").noargs();
    }
}

消费者代码:

java 复制代码
@RequestMapping("/trans")
public String trans() {
    rabbitTemplate.convertAndSend(Constants.TRANS_EXCHANGE,"trans","rabbitmq trans1");
    //制造异常
    int ret = 3/0;
    rabbitTemplate.convertAndSend(Constants.TRANS_EXCHANGE,"trans","rabbitmq trans2");
    return "消息发送成功";
}

这里就不指定消费者了,只是看看事务的效果。

观察队列的情况:

可以发现此时消息的发送是不具备原子性的,所以我们就使用事务保证消息的原子性。

配置事务管理器

java 复制代码
@Configuration
public class TransConfig {
    @Bean("transactionManager")
    public RabbitTransactionManager transactionManager(ConnectionFactory factory) {
        return new RabbitTransactionManager(factory);
    }

    @Bean("transactionRabbitTemplate")
    public RabbitTemplate transactionRabbitTemplate(ConnectionFactory factory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(factory);
        rabbitTemplate.setChannelTransacted(true);
        return rabbitTemplate;
    }
}

加上@Transactional注解

配置完成事务管理器之后,我们需要在需要开启事务的方法上加上 @Transactional 注解:

java 复制代码
@RequestMapping("producer")
@RestController
public class ProducerController {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Resource(name = "transactionRabbitTemplate")
    private RabbitTemplate transactionRabbitTemplate;
    
    @Transactional
    @RequestMapping("/trans")
    public String trans() {
        transactionRabbitTemplate.convertAndSend(Constants.TRANS_EXCHANGE,"trans","rabbitmq trans1");
        //制造异常
        int ret = 3/0;
        transactionRabbitTemplate.convertAndSend(Constants.TRANS_EXCHANGE,"trans","rabbitmq trans2");
        return "消息发送成功";
    }
}

上面就是 RabbitMQ 事务的使用。

相关推荐
岁岁种桃花儿1 小时前
SpringCloud从入门到上天:分布式和微服务基础
分布式·spring cloud·微服务
上海锟联科技7 小时前
DAS 系统 250MSPS 是否足够?——来自上海锟联科技的专业解析
分布式·科技·分布式光纤传感·光频域反射·das
请叫我头头哥8 小时前
SpringBoot进阶教程(八十九)rabbitmq长链接及域名TTL,多机房切换配置重连能力
rabbitmq·springboot
那就学有所成吧(˵¯͒¯͒˵)11 小时前
大数据项目(一):Hadoop 云网盘管理系统开发实践
大数据·hadoop·分布式
徐先生 @_@|||15 小时前
Spark DataFrame常见的Transformation和Actions详解
大数据·分布式·spark
Gofarlic_oms116 小时前
通过Kisssoft API接口实现许可证管理自动化集成
大数据·运维·人工智能·分布式·架构·自动化
走遍西兰花.jpg18 小时前
spark配置
大数据·分布式·spark
hellojackjiang201118 小时前
如何保障分布式IM聊天系统的消息可靠性(即消息不丢)
分布式·网络安全·架构·信息与通信
BYSJMG19 小时前
计算机毕业设计选题推荐:基于Hadoop的城市交通数据可视化系统
大数据·vue.js·hadoop·分布式·后端·信息可视化·课程设计
一只大袋鼠19 小时前
分布式 ID 生成:雪花算法原理、实现与 MyBatis-Plus 实战
分布式·算法·mybatis