课工场 > 文章 >新专栏 > 分布式事务那些事儿
分布式事务那些事儿
陈燕 | 2021-02-20 15:01:45
890

提到事务两个字,相信每一个开发人员都不陌生,从我们第一次开始接触数据库的时候,也就开始和事务打交道;而且是一直打交道,很可能要打一辈子交道。

提到事务两个字,相信每一个开发人员都不陌生,从我们第一次开始接触数据库的时候,也就开始和事务打交道;而且是一直打交道,很可能要打一辈子交道。


为什么这么说呢,大家都知道,互联网经过这么几年快速的发展,互联网技术也更新迭代了很多个版本,从最初的单体架构,到现在的分布式、微服务架构。


系统同样也越来越复杂了,也就意味着问题越来越多了,原来单体架构时的一个小问题,放在了现在可能就是个大问题,需要系统的去解决,就不能像之前那样,凑合过呗,毕竟夫妻和谐也是很重要的。


image.png


所以,单体阶段可能只需要处理好数据库的本地事务就可以了,但是到了分布式系统中,事务的事儿,也就变成了一件大事儿。


这篇文章,我们就来聊聊怎么来处理好这个大事儿,以及现在业内常用的解决方案有哪些?



什么是事务?


为了让大家更好的能理解分布式的那些儿,我们还是先来回顾一下基础的知识,比如第一个概念,什么是事务?咱们先来看下官方的解释。


事务就是用户定义的一系列数据库操作,这些操作可以视为一个完成的逻辑处理工作单元,要么全部执行,要么全部不执行,是不可分割的工作单元。


说人话就是,事务是指程序中一系列严密的逻辑操作,而且所有操作必须全部成功完成,否则在每个操作中所做的所有更改都会被撤销


可以通俗理解为,大家要一起去抢银行,要么都活着回来,要都永远别回来了(牢里),就是一根绳上的蚂蚱,不求同年同月同日生,但求同年同月同日死,听上去还颇有些悲壮的感觉。


image.png


什么是分布式事务?


好了,事务我们知道怎么回事儿了,那什么是分布式事务呢?它有特殊在哪里呢?接下来我们就来一探究竟。


所谓分布式事务,就是指事务的资源分别位于不同的分布式系统的不同节点之上的事务;这个又是啥意思嘞?举个栗子


图片


在早期单体架构时,通常情况下都是单库单表场景,但是现在不是到了分布式环境下了嘛,业务数据非常庞大,所以当业务数据量达到单库单表的极限时,就需要考虑分库分表,将之前的单库单表拆分成多库多表;分库分表之后,原来在单个数据库上的事务操作,可能就变成跨多个数据库的操作,此时就需要使用分布式事务。如果你还不明白,那就再举个栗子


image.png


我们的一个系统有 3个功能模块:用户模块商品模块和订单模块我们现在有一个操作需要按顺序去调用完成这3个模块中的接口,这个操作是一个整体,包含在一个事务中,要么同时成功要么同时失败回滚。不成功便成仁,这个都没有问题。


但是当我们把这个系统拆分成分布式系统架构的时候,事务就不是上面那么玩儿了,原来的用户模块、商品模块和订单模块,都升级变成了用户系统、商品系统和订单系统,每个系统都是独立部署,甚至拥有独立的数据库。


这么一来,分布式事务就复杂多了,怎么才能保证三个不同的系统,针对同一个操作能保持一致性,因为这个三个系统之间要么是RPC通讯,要么是HTTP通信,这就增加了事情的难度。不过,方法总比问题多,程序员是一帮聪明绝顶的人!



分布式事务常见解决方案


分布式事务常见的解决方案,现在通用的基本就如下这三种:

· 两阶段提交(2PC, Two Phase Commit)

· 本地消息表(eBay模式)

· 补偿模式TCC


接下来我们就分别来看下几种解决方案的特点。



两阶段提交(2PC,Two Phase Commit)方案


我们先来看下两阶段提交,两阶段提交其实就是为了保证分布在不同节点上的分布式事务的一致性,我们需要引入一个协调者来管理所有的节点,负责各个本地资源的提交和回滚,并确保这些节点正确提交操作结果,若提交失败则放弃事务。


image.png


它有两个阶段

· 第一阶段:准备阶段(prepare) 协调者通知参与者准备提交订单,参与者开始投票。参与者完成准备工作向协调者回应Yes

· 第二阶段:提交(commit)/回滚(rollback)阶段 协调者根据参与者的投票结果发起最终的提交指令。如果有参与者没有准备好则发起回滚指令



本地消息表(eBay模式


本地消息表,为什么又称为eBay模式呢?那是因为eBay的架构师Dan Pritchett,曾在一篇解释BASE原理的论文《Base:AnAcid Alternative》中提到一个eBay分布式系统一致性问题的解决方案。


栏目分类
关闭
关闭

了解
畅学卡

手机端
学习