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

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景

最近在做某个极其变态的需求,近乎全量的更新整表。本着技术可以解决一切的态度,虽然很不情愿但是还是接下了这个烫手的山芋,于是乎,穷尽自己毕生所学,想到了一个借助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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值