# 消息队列解决方案

## 方案一

有一些第三方的MQ是支持事务消息的，比如RocketMQ，他们支持事务消息的方式也是类似于采用的二阶段提交，但是市面上一些主流的MQ都是不支持事务消息的，比如 RabbitMQ 和 Kafka 都不支持。

以阿里的 RocketMQ 中间件为例，其思路大致为：

第一阶段Prepared消息，会拿到消息的地址。\
第二阶段执行本地事务，第三阶段通过第一阶段拿到的地址去访问消息，并修改状态。

也就是说在业务方法内要想消息队列提交两次请求，一次发送消息和一次确认消息。如果确认消息发送失败了RocketMQ会定期扫描消息集群中的事务消息，这时候发现了Prepared消息，它会向消息发送者确认，所以生产方需要实现一个check接口，RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。

![](https://images2017.cnblogs.com/blog/250417/201710/250417-20171016203840240-13953078.png)

遗憾的是，RocketMQ并没有 .NET 客户端。有关 RocketMQ的更多消息，大家可以查看[这篇博客](http://www.jianshu.com/p/453c6e7ff81c)

**优点：**&#x5B9E;现了最终一致性，不需要依赖本地数据库事务。

**缺点：**&#x5B9E;现难度大，主流MQ不支持，没有.NET客户端，RocketMQ事务消息部分代码也未开源。
