查询资料深入理解分布式事务,高并发下分布式事务的解决方案

自己也是在CSDN上看了很多文章,决定大佬们都写的不错,所以自己也是总结了一些,还是希望和大家进行一个分享。

我觉得不光是在知道它原理的一些所在,当然这固然重要,我觉得能很好的应用到各个项目环境中才是最为关键的。

 

学习的前提:

学习分布式事务的时候首先我们应该先去了解下什么是分布式事务。

什么是分布式事务

在一片博客中看到,分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。当然这是百科上所解释的,我觉得它也很好理解。简单的说,就是说一次大的操作由不同的小的操作组成,而这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务要保证这些小的操作要么全部成功,要么全部失败。本质上来说,分布式事务保证不同的数据库的数据一致性。

 

分布式事务的产生的原因

数据库分库分表情况下 就好比说你表中所产生的数据超过1000w,那么你就好好好考虑下了

业务服务话的情况下 我们分离出来的订单中心,以及库存中心,当然它也有专门的数据库进行保存,为了保证数据的一致性,我们也要好好考虑下。

 

事务的ACID特性

原子性  在整个事务中的所有操作,要么全部完成,要么全部不做,没有中间状态。

一致性  事务的执行必须保证系统的一致性 也就是你转账要保证

隔离性  事务与事务之间不会互相影响,一个事务的中间状态不会被其他事务感知。

持久性  就是说一单事务完成了,那么事务对数据所做的变更就完全保存在了数据库中,即使发生停电,系统宕机也是如此。

我简单在这里说一下,如果需要深入的话可进行详细的查询。

 

分布式事务的应用场景

支付

最经典的场景就是支付了,一笔支付,是对买家账户进行扣款,同时对卖家账户进行加钱,这些操作必须在一个事务里执行,要么全部成功,要么全部失败。而对于买家账户属于买家中心,对应的是买家数据库,而卖家账户属于卖家中心,对应的是卖家数据库,对不同数据库的操作必然需要引入分布式事务。

在线下单

买家在电商平台下单,往往会涉及到两个动作,一个是扣库存,第二个是更新订单状态,库存和订单一般属于不同的数据库,需要使用分布式事务保证数据一致性。

 

这些就是了解分布式事务的前提,当然它也有解决方案。

 

常见的分布式事务解决方案

基于二阶段提交的XA协议

  • 第一阶段:协调者询问所有参与者是否可以执行提交操作,参与者执行准备工作,例如为资源上锁,预留资源。
  • 第二阶段:若所有参与者回应“可提交”,则向所有参与者发送正式提交命令;若某个参与者回应“拒绝提交”,则向所有参与者发送回滚命令。

             

 

  • 我自己是这样理解它的整个过程就是先进行准备事务阶段,写好事务日志并执行事务,但是不进行提交,而此时已经将事务的大部分事情做完,后续的内容耗时就很小。然后事务管理器接受到消息后进行分析,如果有一方失败了则进行回滚命令,否则进行提交命令。

  • 缺点:

    • 它其实就是强一致性,它要确保每执行一步操作,都会记录日志,为出现故障后的恢复准备依据。

    • 还有就是它要确保收到每个资源管理器的响应消息,如果其中一个或多个一直不返回消息,则事务管理器一直等待,应用程序也被阻塞,甚至可能永久阻塞。

消息事务+最终一致性

所谓的消息事务就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功成功并且对外发消息成功,要么两者都失败,开源的RocketMQ就支持这一特性,具体原理如下:

这个是我copy的图 不过写的还是挺详细的

它的流程也是很明确的:

A系统向消息中间件发送一条预报消息,消息中间件保存预备消息并返回成功,A执行本地事务,A发送提交消息给消息中间件,消息中间发消息,B系统的本地操作,其中B系统的操作由消息驱动,只要消息事务成功,那么A操作一定成功,消息也一定发出来了,这时候B会收到消息去执行本地操作,如果本地操作失败,消息会重投,直到B操作成功,这样就变相地实现了A与B的分布式事务。

缺点:

牺牲了一致性换取性能的提升,保证最终的一致性。

当然,这种玩法也是有风险的,如果B一直执行不成功,那么一致性会被破坏,具体要不要玩,还是得看业务能够承担多少风险。

TCC编程模式

首先,所谓的TCC, Try Confirm Cancel,分别对应着确认一个事物完成的简单三个过程,尝试做某件事、确认做某件事、补充的取消做某件事,因为在分布式的事物当中,可能完成一件事情的过程由多个应用一起来完成,那么传统的单机性质的数据库事物已经不能支持多个应用,或者说完成这件事情所涉及的表由多个数据库组成,那么为了保证一致性、原子性,需要将这件事情进行分解,然后再组合起来的方式来共同完成。那么跟TCC相对于的一些其他的解决性方案还有:可靠事件模式(事件的发送和接收保障高可靠性来实现事物一致性)、补偿模式(如果确认失败,全部逆向取消)。
 

 TCC操作事情:

   1、Try:尝试执行业务。

完成所有业务检查(一致性)
预留必须业务资源(准隔离性)
    2、Confirm:确认执行业务。
真正执行业务
不做任何业务检查
只使用Try阶段预留的业务资源
   3、Cancel:取消执行业务
释放Try阶段预留的业务资源
其他事件消息等通知

   TCC操作举例:
   一般系统中执行的积分扣除功能,因为积分扣除这项操作的发起可能是第三方的应用,与积分管理这个服务不在在应用内,为了使得事物一致性,可以使用TCC模式处理。
     1、Try:尝试扣除用户积分,扣除前必须对各项相关数据等做校验,发现不合法的则直接退出,不执行后续操作。这步骤必须保证用户有足够的积分并且可以先扣除,假如后面取消执行业务,可以补回来,但是更多情况是往正常扣除的方向走的。这一点确定了积分扣除记录可以写了。
     2.确认执行业务。在收到另外应用通知,发起扣除的应用业务已经执行完毕,比如积分抽奖或者兑换,收到消息确认没有问题,可以正常扣除积分,因为在try操作上已经真实扣除了积分,这个时候就不用再处理了,只是处理一些事务遗留的一些其他的处理,比如这个事物中一些状态的确认等。
    3.取消执行业务。假如收到第三方应用通知,取消执行业务,那么则需要执行针对try步骤中的事情做回滚,这里不建议删除try的操作,而是执行新增补充的记录来弥补,这个操作需要根据实际的业务来分析,这里只是简单说一下,因为不同业务的回滚操作和性质不一样。在处理完成try步骤的回滚后,后续其他消息的通知也是在这个步骤,比如告知用户操作失败等。
   4.在执行完成上面三个步骤后,其他还是有一定漏洞的,漏洞的引起是因为一些不确定或者系统的性能等引起的,为了保障TCC能够完整无缺,需要做一些其他弥补操作;首先是消息的通知,第三方应用与积分扣除进行了业务隔离,通过消息机制的话,消息有可能丢失,或者网络等原因通知不到位,会导致各种情况,这就要求TCC操作的完整性要好,而一些其他因素会破坏完整性,因此必须做一些弥补确认性的事情,使得完成性出现问题的时候,能够系统自动处理或者人为及时处理。这一步的操作根据不同企业的系统框架使用不一样的处理模式,而且与业务有关系,这里就不再描述。

这个也是在博客上看到的我觉的它说的很有道理,结合项目中的应用应该如何处理。

 

当然说道这里算是三种解决方案了,当然我们也可以采取LCN分布式事务,它是LCN分布式事务框架,笔者也没有更深入的了解,如果需要了解的话 ,可以去看看解决方案。

https://blog.csdn.net/gaowenhui2008/article/details/83824280

这是另外的一个博客,可以去参考下。

 

总结

最后我要进行总结:

分布式事务,本质上是对多个数据库的事务进行统一控制,按照控制力度可以分为:不控制、部分控制和完全控制。不控制就是不引入分布式事务,部分控制就是各种变种的两阶段提交,包括上面提到的消息事务+最终一致性、TCC模式,而完全控制就是完全实现两阶段提交。部分控制的好处是并发量和性能很好,缺点是数据一致性减弱了,完全控制则是牺牲了性能,保障了一致性,具体用哪种方式,最终还是取决于业务场景。作为技术人员,一定不能忘了技术是为业务服务的,不要为了技术而技术,针对不同业务进行技术选型也是一种很重要的能力

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值