学习微服务系列(八):springboot服务分布式事务及解决方案

事务

相信有过研发经验的小伙伴都听过这个词"事务”,什么是事务咱们简单举个生活中的例子:比如你去饭店吃饭,你吃完饭就得给钱结账,你不结账人家饭馆老板就不同意,你给钱了但是老板没给你做菜那么你也不同意。所以这个场景就是双方必须全部成功整个过程才算结束。所以事务的定义就是:

事务可以看做是若干个操作共同组成的一件事,这些子事件要么全部成功,要么全部失败。

本地事务

本地事务其实就是说的是我们传统的单体服务下的数据库事务,我们先回顾一下数据库事务的四大特性 ACID:

  • A(Atomic):原子性,构成事务的所有操作,要么都执行完成,要么全部不执行,不可能出现部分成功部分失 败的情况。
  • C(Consistency):一致性,在事务执行前后,数据库的一致性约束没有被破坏。
  • I(Isolation):隔离性,数据库中的事务一般都是并发的,隔离性是指并发的两个事务的执行互不干扰,一个事 务不能看到其他事务运行过程的中间状态。通过配置事务隔离级别可以避脏读、重复读等问题。
  • D(Durability):持久性,事务完成之后,该事务对数据的更改会被持久化到数据库,且不会被回滚。

如上我们的事务的四个特性,一般我们都是采用spring框架进行开发,所以一般情况都是spring帮我们代理了数据库的事务,比如我们常见的在业务层加上@Transactional注解标识开启事务。

我们从单体服务过渡到分布式服务的过程中就发现在单体服务下的本地事务就失效了。如上图,两个服务或者多个服务进行远程调用存在网络调用,就会出现服务1成功了但是服务2失败了,这样各个服务自己能保证事务进行回滚,但是对于整个调用环节来讲就出现了服务数据不一致,比如服务1是产品服务,服务2是订单服务,订单服务成功了,但是产品服务没有扣减产品。这就出现了数据错误的情况。所以这种情况就需要我们的分布式事务来把控。

分布式事务

分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操 作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务,例如创建订单减产品库存事务,银行转账事务等都是分布式事务。我们简单说一下CAP:CAP是 Consistency、Availability、Partition tolerance三个词语的缩写,分别表示一致性、可用性、分区容忍性。

  • C - Consistency:一致性是指写操作后的读操作可以读取到最新的数据状态,当数据分布在多个节点上,从任意结点读取到的数据都 是最新的状态。
    分布式系统一致性的特点: 1、由于存在数据同步的过程,写操作的响应会有一定的延迟。 2、为了保证数据一致性会对资源暂时锁定,待数据同步完成释放锁定资源。 3、如果请求数据同步失败的结点则会返回错误信息。
  • A - Availability :可用性是指任何事务操作都可以得到响应结果,且不会出现响应超时或响应错误。
    分布式系统可用性的特点: 所有请求都有响应。
  • P - Partition tolerance :分布式系统的各各结点部署在不同网络内,进行网络分区,不可避免的会出现由于网络问题而导致结点之间通信失败,但是此时仍可对外提供服务,这叫分区容忍性。
    一个分布式系统最多只能同时满足 一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)这三项中的两项。对于多数大型互联网应用的场景,结点多、部署分散,因此一般都会做出如下选择:保证P和A,舍弃C强一致,保证最终一致性。

两阶段提交

两阶段提交是将整个事务流程分为两个阶段,准备阶段(Prepare phase)、提交阶段(commit phase),2是指两个阶段,P是指准备阶段,C是指提交阶段。

再来个生活中的例子:如果你们项目组有2个人,你们两个向老板进行汇报项目成果,准备阶段就是老板要求你们两个同时去汇报结果,提交阶段就是老板很满意给你们一笔奖金。这个就是个事务,如果有一个人不去汇报那么老板都不给奖金。整个事务过程由事务管理器和参与者组成,老板就是事务管理器,这两个项目组成员就是事务参与者,事务管理器负责决策整个分布式事务的提交和回滚,事务参与者负责自己本地事务的提交和回滚。

三阶段提交

三阶段提交是基于二阶段提交来到,在提交前增加了一步"CanCommit"询问阶段,事务协调组发送事务请求之前,寻求询问是否可以完成指令,这个过程没有真正的事务操作,这个过程可能有超时而产生事务提交终止。来个图辅助一下理解:

分布式事务常见解决方案

TCC

TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认 Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的 操作即回滚操作。
TCC分为三个阶段:

  1. Try 阶段是做业务检查(一致性)及资源预留(隔离),此阶段仅是一个初步操作,它和后续的Confirm 一起才能 真正构成一个完整的业务逻辑。
  2. Confirm 阶段是做确认提交,Try阶段所有分支事务执行成功后开始执行 Confirm。通常情况下,采用TCC则 认为 Confirm阶段是不会出错的。
  3. Cancel 阶段是在业务执行错误需要回滚的状态下执行分支事务的业务取消,预留资源释放。通常情况下,采用TCC则认为Cancel阶段也是一定成功的。

最终一致性

最终一致性是现在各个公司用的比较多的解决分布式事务的解决方案,因为大部分场景下都可以采用最终一致性来保证多个服务的最终一致。我们可以利用消息中间件比如kafka,rocketMQ的可靠性机制来实现数据投递。比如在支付场景中发起支付后等到三方支付平台异步通知结果,在根据状态来设置支付状态之后在加积分,所以这个环节种支付回调成功后我们会发送一个mq消息到中间件种进行通知加积分服务,完成数据的同步。

最大努力通知

这个最大努力通知其实和上面的最终一致性方案是类似的,比较适用对于数据一致性要求不高的业务场景,通过不断的回调请求进行通知。我们说个场景:

  1. 支付订单后调用支付宝进行支付
  2. 支付宝根据用户的支付情况记录状态
  3. 支付宝回调商户,商户知道通知后进行更改订单状态同时返回给支付宝一个状态告知支付宝我收到了
  4. 理想状态是上面的流程,如果中间有异常支付宝通知商户失败结果丢失这个时候就出现了最大努力通知
  5. 支付宝会1,5,10,30分钟一次调用回调商户的接口进行通知,如果商户还没返回成功则可以通过定时任务处理或者人工处理

Alibaba Seata

为阿里开源分布式事务解决方案,对业务代码入侵很小,其核心就是一个注解"@GlobalTransactional",Seata有3个基本组成部分:

  • 全局唯一事务ID:在同一个ID下的多个库组成一个事务。
  • 事务协调器:   维护全局事务和分支事务的状态,驱动全局提交或回滚。
  • 事务管理器:          定义全局事务的范围:开始全局事务,提交或回滚全局事务。
  • 资源管理器:  管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

  1. 上图每个TM向TC注册全局事务,生成全局唯一XID
  2. RM向TC注册分支事务,并将其纳入该XID对应的全局事务
  3. RM向TC汇报资源的准备状态
  4. TC汇总所有事务参与者的执行状态,决定分布式事务是提交还是回滚
  5. TC通知RM提交或者回滚事务
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值