RocketMQ 事务消息和普通消息是 RocketMQ 针对不同业务场景设计的两种消息类型,核心差异体现在消息生命周期、可靠性机制、使用场景等方面。以下是全方位的对比分析,结合实操场景说明两者的核心区别:
rocketMQTemplate.syncSend("normal_topic", "普通消息内容");
特点:发送后无需关注本地业务,Broker 直接投递,消费者立即收到。
rocketMQTemplate.sendMessageInTransaction("tx_topic", txMessage, null);
特点:消息发送与本地事务强绑定,本地事务失败则消息直接丢弃。
- 普通消息:消息已发送到 Broker,消费者会收到消息(导致「消息发送成功但本地事务失败」的数据不一致);
- 事务消息:生产者回滚「半消息」,Broker 删除消息,消费者收不到(保证一致性)。
- 普通消息:无回查机制,若消息已发送则消费者收到,未发送则失败;
- 事务消息:Broker 定时触发「事务回查」,生产者回查本地事务状态后,提交消息(最终消费者仍能收到)。
- 系统通知:用户注册后发送欢迎短信(即使短信发送失败,不影响注册核心流程);
- 日志采集:应用日志异步发送到日志平台(允许少量丢失,追求高性能);
- 缓存更新:数据库变更后发送消息更新 Redis(即使更新失败,可通过定时任务补偿)。
- 电商订单:订单支付成功(本地事务:扣减用户余额)→ 发送消息创建物流单(必须保证「扣余额成功才发消息」);
- 资金转账:A 账户扣款(本地事务)→ 发送消息给 B 账户加款(必须保证「扣款成功才发消息」);
- 库存扣减:秒杀下单(本地事务:扣减库存)→ 发送消息创建订单(必须保证「扣库存成功才发消息」)。
- 若业务仅需「发消息、收消息」,无本地事务关联 → 用普通消息(高性能、简单);
- 若业务需要「本地事务成功才发消息」,且需保证数据一致性 → 用事务消息(牺牲少量性能换一致性);
- 事务消息必须配合「幂等消费 + 事务状态持久化(如数据库)」,否则回查机制无法生效。