事务处理
按照数据库的经典理论,要达成这个目标,需要三方面共同努力来保障。
- 原子性(Atomic):在同一项业务处理过程中,事务保证了对多个数据的修改,要么同时成功,要么同时被撤销。
- 隔离性(Isolation):在不同的业务处理过程中,事务保证了各自业务正在读、写的数据互相独立,不会彼此影响。
以上四种属性即事务的“ACID”特性,但笔者对这种说法其实不是太认同,因为这四种特性并不正交,A、I、D 是手段,C 是目的,前者是因,后者是果,弄到一块去完全是为了拼凑个单词缩写。
当一个服务只使用一个数据源时,通过 A、I、D 来获得一致性是最经典的做法,也是相对容易的。此时,多个并发事务所读写的数据能够被数据源感知是否存在冲突,并发事务的读写在时间线上的最终顺序是由数据源来确定的,这种事务间一致性被称为“内部一致性”。
当一个服务使用到多个不同的数据源,甚至多个不同服务同时涉及多个不同的数据源时,问题就变得相对困难了许多。此时,并发执行甚至是先后执行的多个事务,在时间线上的顺序并不由任何一个数据源来决定,这种涉及多个数据源的事务间一致性被称为“外部一致性”。
人们在探索这些解决方案的过程中,产生了许多新的思路和概念,有一些概念看上去并不那么直观,在本章里,笔者会通过同一个场景事例讲解如何在不同的事务方案中处理来贯穿、理顺这些概念。
场景事例
- 商品仓库中扣减库存,将商品标识为待配送状态。
- 商家的账号增加相应的商品款项。
接下来,笔者将逐一介绍在“单个服务使用单个数据源”、“单个服务使用多个数据源”、“多个服务使用单个数据源”以及“多个服务使用多个数据源”下,我们可以采用哪些手段来保证数据在以上场景中被正确地读写。