微服务之----分布式事务解决方案
现在的微服务这么流行这么火,分布式的事务是每个系统都会遇到的问题。
CAP定理是由加州大学伯克利分校Eric Brewer教授提出来的,他指出WEB服务无法同时满足一下3个属性:
- 一致性(Consistency) : 客户端知道一系列的操作都会同时发生(生效)
- 可用性(Availability) : 每个操作都必须以可预期的响应结束
- 分区容错性(Partition tolerance) : 即使出现单个组件无法可用,操作依然可以完成
具体地讲在分布式系统中,在任何数据库设计中,一个Web应用至多只能同时支持上面的两个属性。显然,任何横向扩展策略都要依赖于数据分区。因此,设计人员必须在一致性与可用性之间做出选择。
解决方案:
一、两阶段提交(2PC)
核心是:事务协调器, 每个操作都先不提交事务,把是否提交提交事务的结果提交到事务协调器这里,并且告知是否可以提交事务,等所有的都告知处理完了可以提交事务了,这个是由事务协调器一起提交。
二、补偿事务(TCC)
TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。
三、本地消息表(主要是利用消息中间件的 --异步处理机制)
本地消息表这个方案最初是 eBay 提出的,eBay 的完整方案 https://queue.acm.org/detail.cfm?id=1394128
简单点的说,就是利用了本地事务的一致性来保证,最终的事务的一致性
举个简单的例子: A支付系统 B订单系统
我们拿钱去买东西,支付系统在接受到钱支付成功了, 订单系统则要减去对应的订单!
- 在分布式事务操作的一方完成写业务数据的操作之后向本地消息表发送一个消息,本地事务能保证这个消息一定会被写入本地消息表中。
- 之后将本地消息表中的消息转发到 Kafka 等消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发。
- 在分布式事务操作的另一方从消息队列中读取一个消息,并执行消息中的操作。
四、MQ事务
这里不多说,大部分的比如 kafka,rabbitMq 都是不支持事务的
阿里的RocketMQ 据说支持,实现的大体思路
第一阶段Prepared消息,会拿到消息的地址。
第二阶段执行本地事务,第三阶段通过第一阶段拿到的地址去访问消息,并修改状态。
也就是说在业务方法内要想消息队列提交两次请求,一次发送消息和一次确认消息。如果确认消息发送失败了RocketMQ会定期扫描消息集群中的事务消息,这时候发现了Prepared消息,它会向消息发送者确认,所以生产方需要实现一个check接口,RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。