spring-amqp以事物机制向mq发送消息

在处理需要数据库和MQ同步操作的场景中,使用Spring AMQP时遇到问题,即异常情况下消息仍被发送并消费,影响数据一致性。通过分析发现Spring AMQP提供channelTransacted属性启用事务,确保消息发送与数据库操作原子性。但在配置中,事务机制与发送方确认机制冲突引起错误。解决方案是禁用publisher-confirms配置,以允许事务机制正常工作。

场景

最近在做某个极其变态的需求,近乎全量的更新整表。本着技术可以解决一切的态度,虽然很不情愿但是还是接下了这个烫手的山芋,于是乎,穷尽自己毕生所学,想到了一个借助mq异步多线程更新的还算凑合的办法。兴致勃勃的写完了,结果发现一个问题:由于最近刚刚切到spring-amqp框架,代码中使用rabbitTemplate发送消息后,如果遇到异常,消息还是会被发送到mq并且被消费者消费,此时我的业务逻辑还涉及到数据库的更新操作,如此一来岂不是一致性得不到保证,并且为了最大限度的分散更新压力,充分利用集群机器,我将每个表的更新分三条消息发送给mq,如果其中两条发送了到第三条没有发送成功,有两个消息被消费,一个没有被消费岂不是很尴尬。

问题

如何保证在spring事物中的数据库操作和mq发送消息的操作在一个事物中,即原子性,要么全部执行,要么全部回滚。

分析

由于对amqp发送的基础包操作很熟练,知道有一个事物机制发送消息,就是为了保证在异常出现时可以让mq服务器返回消息,而不至于被错误的消费。大体云云就是channel.txSelect()开启事物,然后basic发送消息,最后正常的话channel.txCommit提交事物,此时消息真正的发送到队列中去。如果有异常rollback即可。想到spring-amqp这么高级的框架肯定也会有这个操作的,果不其然让我发现了眉目,通过配置文件发线一个属性参数channelTransacted,通过一部分源码发现:

private <T> T doExecute(ChannelCallback<T> action, ConnectionFactory connectionFactory) {
		Assert.notNull(action, "Callback object must not be null");
		Channel channel = null;
		boolean invokeScope = false;
		// No need to check the thread local if we k
### 区别与关系 `spring-boot-starter-amqp`、`amqp-client` 和 `spring-amqp` 是在使用 AMQP(Advanced Message Queuing Protocol)协议进行消息传递时常见的三个组件,它们在功能和使用场景上有明确的分工和依赖关系。 `amqp-client` 是 RabbitMQ 官方提供的底层 Java 客户端库,用于与 RabbitMQ 服务器进行通信。它提供了基础的连接、通道、发布和消费消息的 API,适用于直接操作 RabbitMQ 的场景,但需要手动管理连接和资源[^1]。 `spring-amqp` 是 Spring 框架对 AMQP 协议的抽象和封装,提供了一套高层次的 API,简化了与 RabbitMQ 的集成。它基于 `amqp-client`,并提供了诸如 `RabbitTemplate`、消息监听容器等高级功能,使得开发者可以更方便地发送和接收消息[^1]。 `spring-boot-starter-amqp` 是 Spring Boot 提供的一个启动器依赖,集成了 `spring-amqp` 和 `amqp-client`,并提供了自动配置功能。通过简单的配置,即可快速构建基于 RabbitMQ消息生产者和消费者,极大地简化了开发流程[^1]。 ### 依赖关系示例 以下是一个典型的 `pom.xml` 配置片段,展示了 `spring-boot-starter-amqp` 如何集成其他两个库: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 此依赖会自动引入 `spring-amqp` 和 `amqp-client`,无需额外添加。 ### 功能对比 | 组件名称 | 功能描述 | 是否需要手动管理资源 | |------------------------|--------------------------------------------------------------------------|----------------------| | `amqp-client` | RabbitMQ 官方提供的基础客户端库,支持直接与 RabbitMQ 进行通信 | 是 | | `spring-amqp` | SpringAMQP 的封装,提供高层次的 API,简化消息操作 | 否 | | `spring-boot-starter-amqp` | Spring Boot 启动器,集成 `spring-amqp` 和 `amqp-client`,提供自动配置功能 | 否 | ### 使用场景 - **`amqp-client`**:适用于需要精细控制 RabbitMQ 连接和消息传递的场景,适合对 RabbitMQ 有深入了解的开发者。 - **`spring-amqp`**:适用于希望在 Spring 项目中快速集成 RabbitMQ,但不需要 Spring Boot 自动配置功能的场景。 - **`spring-boot-starter-amqp`**:适用于 Spring Boot 项目,希望快速集成 RabbitMQ 并利用自动配置功能简化开发流程的场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值