> For the complete documentation index, see [llms.txt](https://chanshiyu.gitbook.io/blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://chanshiyu.gitbook.io/blog/hou-duan/li-lun-gai-nian/09-ji-yu-xiao-xi-dui-lie-de-fen-bu-shi-shi-wu-jie-jue-fang-an.md).

# 09 基于消息队列的分布式事务解决方案

> 本文为个人学习摘要笔记。\
> 原文地址：[基于消息队列的分布式事务解决方案](https://mp.weixin.qq.com/s/Ga7ziVyc6C1uUXbON0t5qA)

## 数据库事务

数据库事务具有 ACID 这 4 个特性：

* A：Atomic，原子性，将所有 SQL 作为原子工作单元执行，要么全部执行，要么全部不执行；
* C：Consistent，一致性，事务完成后，所有数据的状态都是一致的，即 A 账户只要减去了 100，B 账户则必定加上了 100；
* I：Isolation，隔离性，如果有多个事务并发执行，每个事务作出的修改必须与其他事务隔离；
* D：Duration，持久性，即事务完成后，对数据库数据的修改被持久化存储。

对于单条 SQL 语句，数据库系统自动将其作为一个事务执行，这种事务被称为隐式事务。

## CAP 理论

CAP 理论是由加州大学 Eric Brewer 教授提出来的，这个理论告诉我们，一个分布式系统不可能同时满足一致性（Consistency）、可用性（Availability）、分区容错性（Partition tolerance）这三个基本需求，最多只能同时满足其中两项。

* **一致性**：这里的一致性是指数据的强一致，也称为线性一致性。是指在分布式环境中，数据在多个副本之间是否能够保持一致的特性。也就是说对某个数据进行写操作后立马执行读操作，必须能读取到刚刚写入的值。（any read operation that begins after a write operation completes must return that value, or the result of a later write operation）
* **可用性**：任意被无故障节点接收到的请求，必须能够在有限的时间内响应结果。（every request received by a non-failing node in the system must result in a response）
* **分区容错性**：如果集群中的机器被分成了两部分，这两部分不能互相通信，系统是否能继续正常工作。（the network will be allowed to lose arbitrarily many messages sent from one node to another）

**在分布式系统中，分区容错性是基本要保证的**。也就是说只能在一致性和可用性之间进行取舍。一致性和可用性，为什么不可能同时成立？回到之前修改列表的例子，由于数据会分布在不同的网络分区，必然会存在数据同步的问题，而同步会存在网络延迟、异常等问题，所以会出现数据的不一致！如果要保证数据的一致性，那么就必须在对写库进行操作时，锁定其他读库的操作。只有写入成功且完成数据同步后，才能重新放开读写，而这样在锁定期间，系统丧失了可用性。

## 分布式事务

不管是本地事务，还是分布式事务，都是为了解决数据的一致性问题！与本地事务不同的是，分布式事务需要保证的是分布式环境下，不同数据库表中的数据的一致性问题。分布式事务的解决方案有多种，如 XA 协议、TCC 三阶段提交、基于消息队列等等。
