1. 分布式事务介绍
1.1 分布式的介绍
首先呢,分布式的发展生离不开云计算,微服务,分库分表等技术的发展。
分布式一般指代分布式服务,所谓分布式服务就是我们将服务部署于不同机器(物理机,虚拟机),让他们一起为我们提供服务,分布式服务可以说是单节点服务的扩展,单节点服务能力是有限的,我们通过拓展节点提升服务的能力。
1.2 事务的介绍
事务一般指代数据库事务,同一个事务操作能够保证其具有ACID四大特性。
- 原子性(Atomicity) :要么都成功要么都失败。
- 一致性(Consistency) :AID都是数据库处理的特征,一致性是强调应用系统从一个正确的状态到另一个正确的状态,可以说AID是为了保证C。
- 隔离性(Isolation) :多个事务同时处理相同数据,事务间会互相隔离,不会互相影响。
- 持久性(Durability) :事务完成,会将结果持久化到磁盘。
1.3 分布式事务
如果是同一服务操作同一数据库,Spring就可以很好的为我们解决事务问题,这种情况下是不存在分布式事务的。
什么是分布式事务?
分布式事务就是在数据库事务无法保证数据一致性,借助其他手段来保证数据的一致性。
这里的一致性需要参考CAP理论和BASE理论,它可以是强一致性,也可以是最终一致性。
分布式事务的产生可以归咎于两个原因:
- 应用服务的多节点
从早期的SOA到现在的微服务,应用细粒度拆分成为一种趋势,不同的业务能力被拆分成多个服务,有些业务是相互关联的,比如商品,订单,积分等分配到不同的服务中,但是用户下单的时候,就需要扣减商品库存,增加用户积分,扣除用户余额,这样下单流程就会产生服务间的互相调用。这样我们就需要去保证这一系列操作的一致性,这时就需要分布式事务来解决。
- 数据库服务的多节点
随着互联网的发展,各个公司拥有的数据量也在突飞猛涨,分库分表技术也日趋成熟,对于MySQL数据库来说单表数据量达到五千万就需要进行分库分表。事务是数据库层面,但凡是操作不同的数据库就会无法保证是同一个事务,需要使用分布式事务来处理。
2. 分布式事务的解决方案
本篇文章不会花大量篇幅讲述分布式事务的解决方案,后期会专门写一篇文章深入讲解一下。
二阶段提交(2PC)
- XA
XA是一个分布式事务协议,由Tuxedo提出。XA中大致分为两部分:事务管理器和本地资源管理器。其中本地资源管理器由数据库实现,比如主流的数据库Oracle、Mysql等数据库都实现了XA接口,而事务管理器作为全局的调度者,负责各个本地资源的提交回滚。
- AT
Seata中的一种实现方式,全局事务,无倾入性。
- XA
- 三阶段提交(3PC)
3PC其实在2PC的基础上增加了CanCommit阶段,是2PC的变种,并引入了超时机制。
补偿事务
- Saga
记录回滚方案,如果一个正向操作执行失败,那么分布式事务会去执行前面各参与者的逆向回滚操作,使其回到初始状态。
- TCC
TCC是基于业务逻辑去实现,对代码侵入性很强。它与2PC很像,但是需要应用自己去实现,所有的业务逻辑都需要实现try、confirm、cancel三个操作。
- Saga
- 本地消息表(最终一致性)
在数据库中加一张消息表,通过改状态,加定时任务,与消息事物类似,也是保证最终一致性
- 消息事务(最终一致性)
消息事务是借助消息中间件来实现分布式事务,此种方式是保证最终一致性。
这里肯定有人疑惑为什么没有Seata,Seata实际是对上面几种方式的实现,Seata有四种模式AT、XA、Saga、TCC,AT和XA都是基于2PC的方式。
3. 避免分布式事务
分布式事务的性能其实是很低的,往往在我们的服务拆分后,加入大量的分布式事务,看似很高大上。但是用过分布式事务的才知道分布式事务的坑有多少,本身数据库事务就很耗费资源,我们还加强了事务的复杂度,不但服务响应速度会受影响,出了错误也比较难排查,有时候本应该回滚的事物确没有回滚,或者部分回滚都是很让人恼火的事情。
所以说我们一定要尽量避免分布式事务,防止过度设计。