分布式事务消息(RocketMQ事务消息实现)
请详细介绍RocketMQ的事务消息如何实现分布式事务。半消息(Half Message)是什么?事务回查机制如何工作?和Seata AT模式相比有什么优缺点?
回答
编译有声
RocketMQ事务消息原理:
流程:
- 生产者发送半消息(Half Message)到RocketMQ Broker
- 半消息对消费者不可见(暂存在特殊Topic)
- Broker持久化半消息成功,返回OK给生产者
- 生产者执行本地事务(如扣库存、创建订单)
- 生产者提交Commit或Rollback给Broker
- 若Commit,半消息变为可见(消费者可消费);若Rollback,删除半消息
事务回查机制:
- 如果Broker长时间(默认60秒)未收到Commit/Rollback
- Broker主动回调生产者接口(checkLocalTransaction)
- 生产者检查本地事务状态,返回COMMIT_MESSAGE/ROLLBACK_MESSAGE/UNKNOWN
- 防止生产者宕机导致事务悬空
代码示例:
@RocketMQTransactionListener
public class OrderTransactionListener implements RocketMQLocalTransactionListener {
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
try {
// 执行本地事务(创建订单、扣库存)
orderService.createOrder((Order)arg);
return RocketMQLocalTransactionState.COMMIT;
} catch (Exception e) {
return RocketMQLocalTransactionState.ROLLBACK;
}
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
// 回查:检查订单是否存在
String orderId = msg.getUserProperty("orderId");
return orderService.exists(orderId) ?
COMMIT : ROLLBACK;
}
}
RocketMQ事务消息 vs Seata AT模式:
| 对比 | RocketMQ事务消息 | Seata AT |
|---|---|---|
| 耦合度 | 低(通过MQ解耦) | 低(字节码增强,无侵入) |
| 一致性 | 最终一致性 | 强一致性(AT) |
| 性能 | 高(异步+解耦) | 较低(持有数据库行锁) |
| 适用 | 跨服务跨DB的最终一致性场景 | 同一DB内跨表强一致性 |
| 复杂性 | 需保证幂等消费 | 需部署TC服务 |
总结:事务消息适合最终一致性场景(订单→积分→短信);Seata AT适合强一致性场景(跨库转账)。