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 事务的使用。

相关推荐
ACP广源盛1392462567311 小时前
DeepSeek‑V4‑Flash 公测@ACP#昇腾 950 国产算力组合落地,国产 PCIe 交换芯片 IX9104 有哪些硬件机会
大数据·数据库·人工智能·分布式·单片机·嵌入式硬件·microsoft
玉鸯12 小时前
多 Agent 并行时如何保证状态一致性?
分布式·python·agent
CodeHackerBhx13 小时前
Spring Boot 4 防重复提交:从接口幂等到 Redis 分布式锁的完整实践
java·数据库·spring boot·redis·分布式
城管不管16 小时前
RabbitMQ死信队列
java·分布式·ai·面试·职场和发展·rabbitmq·agent
城管不管16 小时前
rabbitmq如何保证消息不丢失?解决方案又是什么?
开发语言·ai·面试·职场和发展·rabbitmq·php·agent
2601_9564563416 小时前
从研发到交付:嗨动视觉分布式KVM坐席系统的靠谱逻辑
分布式
小O的算法实验室17 小时前
AAAI-26,解空间变换引导的节能分布式异构柔性作业车间协同进化
分布式
六点_dn1 天前
RabbitMQ学习笔记-部署和使用
笔记·学习·rabbitmq
ai_coder_ai1 天前
分布式缓存架构设计与实践
分布式·缓存
纯真时光1 天前
微服务分布式事务 -- XA,AT,TCC模式
分布式·微服务