一次给女朋友转账引发我对分布式事务的思考

  • 时间:
  • 浏览:10
  • 来源:QQ核心乐园_提供QQ业务乐园技术_空间引流吧资讯

   时候都肯能从我卡里扣过钱了,现在却提示我转账失败,银行会我不要 把我的钱给吞了?转账失败的钱还能退换给我吗?正在我紧张、焦虑、坐立不安之时又收到二根app冲正的消息,时候转账失败的钱肯能退还给我了,看来我多虑了……这也证明咱平安银行的app还是比较安全靠谱的!

1、A银行对转出账户执行检查校验,进行金额扣减。

2、A银行同步调用B银行转账接口。

3、B银行对转入账户进行检查校验,进行金额增加。

4、B银行返回处置结果给A银行。

   通过上面的图亲戚亲戚这各自 能看完,引入消息队列后,系统的繁复性瞬间提升了,全是本来弥补了亲戚亲戚这各自 第某种方案的哪几只欠缺点,但也带来了更多的這個的现象,比如消息队列系统某种的可用性、消息队列的延迟等等!而且,从前 的设计依然没有处置亲戚亲戚这各自 面临的核心這個的现象-数据的一致性

1、A银行对账户进行检查校验,进行金额扣减。

2、将对B银行的请求异步写入队列,主线程返回。

3、启动后台线程从队列获取待处置数据。

4、后台线程对B银行接口进行远程调用。

5、B银行对转入账户进行检查校验,进行金额增加。

6、B银行处置完成回调A银行接口通知处置结果。

   缘何从我卡里扣钱没有没有快了 了 ,而对方却要几秒也能到账?而且转账失败后,扣除的钱还能及时的返还到我的卡里?万一钱返还失败缘何办?又肯能我转一次钱,对方却收到了两次转账的申请又该如何?带着這個這個的现象,我脑海中浮现出“事务”二字!

   同样的,亲戚亲戚这各自 都还要在B银行系统中还要增加另另一个转账日志表,肯能叫转账流水表,B银行每次接收到转账请求,在对账户进行操作的时候一起去往转账日志表中插入二根转账日志记录,同样这每每各自 操作也还本来原子的!在接收到转账请求后,首先根据唯一转账流水Id在日志表中查找判断该转账是与否肯能处置过,肯能未处置过则进行处置,而且直接回调返回! 最终的架构图如下:

  

   然而,一切并没有没有顺利,刚过一会儿,app却如图二所示的提示我“肯能收款人户名不符”是原因分析分析转账失败!!!

  还记得刚毕业那年,带着满腔的热血就去到了一家互联网公司,领导给我的第另另一个任务好多好多 在列表上增加另另一个修改数据的功能。这能难倒我?我分分钟让你搞出来!不好多好多 在列表上增加了另另一个“修改”按钮,点击按钮弹出框修改后保存就好了么。然而一切不像我还要 象的没有顺利,点击保存并刷新列表后,页面上的数据还是显示的修改时候的内容,像没有修改成功一样!过一会儿再刷新列表,数据就能正常显示了!测试多次时候全是从前 !没见过這個大场面的我开始英语 英语 了了一阵一阵慌了,是我哪里写得不对么?最终,我不得不求助组内经验比较富有的前辈!他深吸了一口气告诉跟我说:“毕竟是刚毕业的小伙子啊!我来跟你讲讲是原因分析分析吧!亲戚亲戚这各自 的数据库是做了读写分离的,要素读库与写库在不同的网络分区。你的数据更新到了写库,而读数据的时候是从读库读取的。更新到写库的数据同步到读库是有一定的延迟的,也好多好多 说读库与写库会有短暂的数据不一致”! “从前 我不要 体验不好么?为這個不到做到写入的数据立马能读出来?从前 這個功能该缘何实现呢?” 面对我的一堆這個的现象,同事這個不耐烦的说:“听说过CAP理论吗?你先另一方去了解一下吧”!是我开始英语 英语 了了查阅各种资料去了解這個陌生的词手中的秘密!

   本地事务讲到了一致性,分布式事务不可处置的面临着一致性的這個的现象!回到最开始英语 英语 了了跨行转账的例子,肯能A银行用户向B银行用户转账,正常流程应该是:

  

  

   面对上述這個的现象,亲戚亲戚这各自 不得不对系统再次进行升级改造。为了处置“A银行账户扣款了,而且写入消息队列失败”的這個的现象,亲戚亲戚这各自 还要借助另另一个转账日志表,肯能叫转账流水表,该表简单的设计如下:

  

  CAP理论是由加州大学Eric Brewer教授提出来的,這個理论告诉亲戚亲戚这各自 ,另另一个分布式系统不肯能一起去满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)这每每各自 基本需求,最多不到一起去满足其中两项。

  一致性:这里的一致性是指数据的强一致,也称为线性一致性。是处于分布式环境中,数据在多个副本之间是与否也能保持一致的特征。也好多好多 说对某个数据进行写操作后立马执行读操作,还也能读取到时候写入的值。(any read operation that begins after a write operation completes must return that value, or the result of a later write operation)

  可用性:任意被无故障节点接收到的请求,还要也能在有限的时间内响应结果。(every request received by a non-failing node in the system must result in a response)

  分区容错性:肯能集群中的机器被分成了两要素,这两要素不到互相通信,系统是与否能继续正常工作。(the network will be allowed to lose arbitrarily many messages sent from one node to another)

   到目前为止,亲戚亲戚这各自 很好的处置了消息丢失的這個的现象,保证了我希望A银行转账操作成功,转账的请求就一定能发送到B银行!而且该方案又引入了另另一个這個的现象,通时候台线程轮询将消息放上消息队列处置,同一次转账请求肯能会出显多次放上消息队列而多次消费的请况,从前 B银行会对同一转账多次处置是原因分析分析数据出显不一致!那缘何保证B银行转账接口的幂等性呢?

   這個流水表还要缘何用呢?亲戚亲戚这各自 在“第1步”进行扣款时,一起去往流水表写入二根操作流水,请况为“待处置”,而且这每每各自 操作还本来原子的,也好多好多 说还要通过本地事务保证这每每各自 操作要么一起去成功,要么一起去失败!这就保证了我希望转账扣款成功,必定会记录二根请况为“待处置”的转账流水。肯能在這個步失败了,那自然好多好多 转账失败,没有后续操作了。肯能这步操作后系统宕机了是原因分析分析没有将消息成功写入消息队列(也好多好多 “第2步”)也没关系,肯能亲戚亲戚这各自 的流水数据肯能持久化了!这时候亲戚亲戚这各自 只还要加入另另一个后台线程进行补偿,定期的从转账流水表中读取请况为“待处置”且最后更新的时间距当前时间大于某个阈值的数据,重新放上消息队列进行补偿。从前 ,就保证了消息即使丢失,也会有补偿机制!B银行在处置完转账请求总要回调A银行的接口通知转账的请况,从而更新A银行流水表中的请况字段!从前 就完美处置了上另另一个方案中的另另一个欠缺点。系统设计图如下:

  

1、肯能“第1步”刚执行完,系统肯能某种是原因分析分析宕机了,那会是原因分析分析A银行账户扣款了,而且写入消息队列失败,无法进行B银行接口调用,从本来原因分析分析数据不一致。

2、肯能B银行在执行“第5步”时肯能校验失败而未能成功转账,在回调A银行接口通知回滚时网络异常肯能宕机,会是原因分析分析A银行转账无法完成回滚,从本来原因分析分析数据不一致。

   谈到本地事务,亲戚亲戚这各自 肯能都半生不熟悉,肯能這個数据库引擎层面能支持的!好多好多 也称数据库事务,数据库事务四大特征:原子性(A),一致性(C),隔离性(I)和持久性(D),而在这四大特征中,我认为一致性是最基本的特征,其它的另另一个特征都为了保证一致性而处于的!

   好多好多 ,亲戚亲戚这各自 这里最核心的好多好多 A银行通过本地事务保证日志记录+后台线程轮询保证消息不丢失。B银行通过本地事务保证日志记录从而保证消息不重复消费!B银行在回调A银行的接口总要通知处置结果,肯能转账失败,A银行会根据处置结果进行回滚。

   对于這個的现象的1、2都很好处置,肯能对消息队列熟悉的亲戚亲戚这各自 应该减慢能想到都还要引入消息上面件进行异步和削峰处置,于是又重新设计了另另一个方案,流程如下:

   在亲戚亲戚这各自 还在“牙牙学语”的时候,老师总是会通过转账的栗子来跟亲戚亲戚这各自 讲解事务,但跟这里场景不一样的是,老师讲的是本地事务,而这上面对的是分布式事务!亲戚亲戚这各自 先来简单回顾一下本地事务!

   在正常请况对一致性要求不高的场景,从前 的设计是都还要满足需求的。而且像银行从前 的系统,肯能从前 实现至少早就破产了吧。亲戚亲戚这各自 先看看从前 的设计最主要的這個的现象:

1、同步调用远程接口,肯能接口比较耗时,会是原因分析分析主线程阻塞时间较长。

2、流量不到很好控制,A银行系统的流量高峰肯能压垮B银行系统(当然B银行肯定会有另一方的限流机制)。

3、肯能“第1步”刚执行完,系统肯能某种是原因分析分析宕机了,那会是原因分析分析A银行账户扣款了,而且B银行没有收到接口的调用,这就出显了另另一个系统数据的不一致。

4、肯能在执行“第3步”后,B银行肯能某种是原因分析分析宕机了而无法正确签署请求(实际上转账操作在B银行系统肯能执行且入库),这时候A银行等待英文接口响应会异常,误以为转账失败而回滚“第1步”操作,这也会出显了另另一个系统数据的不一致。

   前两天发了工资,第一反应是想着要给远方的女亲戚亲戚这各自 這個惊喜!于是打开了平安银行的APP给女亲戚亲戚这各自 转点钱!填写上对方招商银行卡的卡号、开户名,一键转账!拿出!在我点击的那瞬间,就收到了app的账户变动的提醒,而且出显了图一所示的提示界面:“处置中,正等待英文英文对方银行返回结果…”。嗯!毕竟是跨行转账嘛,等个几秒也正常!脑海开始英语 英语 了了浮现出女亲戚亲戚这各自 收到转账后惊喜与感动的画面!

   当然,分布式事务最好的处置方案是尽量处置出显分布式事务!

本文在另一方技术博客不同步发布,详情可用力戳

亦可扫描屏幕右侧二维码关注另一方公众号,公众号内有另一方联系土办法,等你来撩...

   分布式事务好多好多 在分布式的场景下,还要满足事务的需求!上篇文章亲戚亲戚这各自 聊过了消息上面件,那这篇文章亲戚亲戚这各自 要聊的是分布式事务,把两者一结合,便有了基于消息上面件的分布式事务处置方案!不管是本地事务,还是分布式事务,全是为了处置数据的一致性這個的现象!一致性這個词咱们前面多次提及!与本地事务不同的是,分布式事务还要保证的是分布式环境下,不同数据库表中的数据的一致性這個的现象。分布式事务的处置方案有多种,如XA协议、TCC三阶段提交、基于消息队列等等,本文只会涉及基于消息队列的处置方案!

  

  在分布式系统中,分区容错性是基本要保证的。也好多好多 说不到在一致性和可用性之间进行选则。一致性和可用性,为這個不肯能一起去成立?回到时候修改列表的例子,肯能数据会分布在不同的网络分区,必然会处于数据同步的這個的现象,而同步会处于网络延迟、异常等這個的现象,好多好多 会出显数据的不一致!肯能要保证数据的一致性,没有就还要在对写库进行操作时,锁定這個读库的操作。不到写入成功且完成数据同步后,也能重新放开读写,而从前 在锁定期间,系统丧失了可用性。更完全关于CAP理论都还要参考这篇文章,该文章讲得比较通俗易懂!

   回到学生时代老师给亲戚亲戚这各自 举的经典栗子,A账户给B账户转账5000元(A、B处于同另另一个库中),肯能A的账户处于扣款,B的账户却没有到账,这就出显了数据的不一致!为了保证数据的一致性,数据库的事务机制会让A账户扣款和B在账户到账的另另一个操作要么一起去成功,肯能有另另一个操作失败,则多个操作一起去回滚,这好多好多 事务的原子性,为了保证事务操作的原子性,就还要实现基于日志的REDO/UNDO机制!而且,仅有原子性还欠缺,肯能亲戚亲戚这各自 的系统是运行在线程环境下,肯能多个事务并行,即使保证了每另另一个事务的原子性,仍然会出显数据不一致的请况。相似于A账户从前 有500元的余额, A账户给B账户转账5000元,先读取A账户的余额,而且在這個值上减去5000元,而且在这每每各自 操作之间,A账户又给C账户转账5000元,没有最后的结果应该是A减去了500元。但事实上,A账户给B账户最终完成转账后,A账户只减掉了5000元,肯能A账户向C账户转账减掉的5000元被覆盖了!好多好多 为了保证并发请况下的一致性,又引入的隔离性,即多个事务并发执行后的请况,和它们串行执行后的请况是等价的!隔离性又有多种隔离级别,为了实现隔离性(最终全是为了保证一致性)数据库又引入了悲观锁、乐观锁等等……本文的主题是分布式事务,好多好多 本地事务就好多好多 简单回顾一下,还要记住的這個是,事务是为了保证数据的一致性