要保证事务提交后 MQ 才消费,可以使用 MQ 的事务消息功能。Spring Cloud Stream 集成了 RocketMQ 的事务消息功能,可以使用@Transactional注解和RocketMQTransactionListener来实现。

首先,在 Spring Boot 的订单方法上添加@Transactional注解,确保方法中的数据库操作在一个事务中。这样,如果方法执行成功,则事务会被提交;如果方法执行失败,则事务会被回滚。

@Transactional
public void updateOrderAndInventory() {
    // 修改订单信息
    // 修改库存信息
}

接下来,配置 RocketMQ 的事务消息监听器RocketMQTransactionListener。该监听器实现了 RocketMQ 的事务消息接口,可以在其中编写本地事务和消息发送逻辑。

@Component
public class MyRocketMQTransactionListener implements RocketMQLocalTransactionListener {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        try {
            // 执行本地事务(修改 ES 库存)
            // 如果本地事务执行成功,则返回 COMMIT 状态,否则返回 ROLLBACK 状态
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(MessageExt msg) {
        // 根据消息的状态判断本地事务的执行结果
        // 如果本地事务已提交,则返回 COMMIT 状态;如果本地事务已回滚,则返回 ROLLBACK 状态
        // 如果本地事务还在进行中,则返回 UNKNOWN 状态
        return RocketMQLocalTransactionState.UNKNOWN;
    }
}

然后,在订单方法中调用 RocketMQ 发送事务消息,将本地事务的执行结果作为消息的附加信息发送给 RocketMQ。

@Autowired
private RocketMQTemplate rocketMQTemplate;

@Transactional
public void updateOrderAndInventory() {
    // 修改订单信息
    // 修改库存信息

    // 发送事务消息
    rocketMQTemplate.sendMessageInTransaction('topic', 'message', 'transactional-arg');
}

最后,在配置文件中添加 RocketMQ 的事务消息监听器配置。

spring:
  cloud:
    stream:
      rocketmq:
        binder:
          transaction:
            listener:
              enable: true

这样,当订单方法执行成功并提交事务时,RocketMQ 会收到事务消息,并调用RocketMQTransactionListenerexecuteLocalTransaction方法执行本地事务。只有在本地事务执行成功并返回 COMMIT 状态时,RocketMQ 才会将消息发送给消费者消费,从而保证了事务提交后 MQ 才消费的顺序。如果本地事务执行失败并返回 ROLLBACK 状态,RocketMQ 会将消息进行回滚。

注意,要确保在 RocketMQ 的事务监听器中执行的本地事务和数据库事务是同一个事务,可以使用同一个数据库连接或者使用分布式事务框架(如 Seata)来管理事务。

SpringBoot 事务消息:解决数据库事务与RocketMQ消费顺序不一致问题

原文地址: http://www.cveoy.top/t/topic/pb3W 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录