加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡阳站长网 (https://www.0734zz.cn/)- 数据集成、设备管理、备份、数据加密、智能搜索!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

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

发布时间:2019-06-26 18:14:46 所属栏目:优化 来源:IT技术分享
导读:前两天发了工资,第一反应是想着要给远方的女朋友一点惊喜!于是打开了平安银行的APP给女朋友转点钱!填写上对方招商银行卡的卡号、开户名,一键转账!搞定!在我点击的那瞬间,就收到了app的账户变动的提醒,并且出现了图一所示的提示界面:处理中,正在等待
副标题[/!--empirenews.page--]

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

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

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

然而,一切并没有那么顺利,刚过一会儿,app却如图二所示的提示我“由于收款人户名不符”导致转账失败!!!

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

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

为啥从我卡里扣钱那么迅速,而对方却要几秒才能到账?并且转账失败后,扣除的钱还能及时的返还到我的卡里?万一钱返还失败怎么办?又或者我转一次钱,对方却收到了两次转账的申请又该如何?带着这些问题,我脑海中浮现出“事务”二字!

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

本地事务

谈到本地事务,大家可能都很熟悉,因为这个数据库引擎层面能支持的!所以也称数据库事务,数据库事务四大特征:原子性(A),一致性(C),隔离性(I)和持久性(D),而在这四大特性中,我认为 一致性 是最基本的特性,其它的三个特性都为了保证一致性而存在的!

回到学生时代老师给我们举的经典栗子,A账户给B账户转账100元(A、B处于同一个库中),如果A的账户发生扣款,B的账户却没有到账,这就出现了 数据的不一致 !为了保证数据的一致性,数据库的事务机制会让A账户扣款和B在账户到账的两个操作要么同时成功,如果有一个操作失败,则多个操作同时回滚,这就是事务的 原子性 ,为了保证事务操作的原子性,就必须实现基于日志的REDO/UNDO机制!但是,仅有原子性还不够,因为我们的系统是运行在多线程环境下,如果多个事务并行,即使保证了每一个事务的原子性,仍然会出现数据不一致的情况。例如A账户原来有200元的余额, A账户给B账户转账100元,先读取A账户的余额,然后在这个值上减去100元,但是在这两个操作之间,A账户又给C账户转账100元,那么最后的结果应该是A减去了200元。但事实上,A账户给B账户最终完成转账后,A账户只减掉了100元,因为A账户向C账户转账减掉的100元被覆盖了!所以为了保证并发情况下的一致性,又引入的 隔离性 ,即多个事务并发执行后的状态,和它们串行执行后的状态是等价的!隔离性又有多种隔离级别,为了实现隔离性(最终都是为了保证一致性)数据库又引入了悲观锁、乐观锁等等……本文的主题是分布式事务,所以本地事务就只是简单回顾一下,需要记住的一点是,事务是为了保证数据的 一致性 !

分布式理论

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

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)

在分布式系统中,分区容错性是基本要保证的。也就是说只能在一致性和可用性之间进行取舍。一致性和可用性,为什么不可能同时成立?回到之前修改列表的例子,由于数据会分布在不同的网络分区,必然会存在数据同步的问题,而同步会存在网络延迟、异常等问题,所以会出现数据的不一致!如果要保证数据的一致性,那么就必须在对写库进行操作时,锁定其他读库的操作。只有写入成功且完成数据同步后,才能重新放开读写,而这样在锁定期间,系统丧失了可用性。更详细关于CAP理论可以参考 这篇文章 ,该文章讲得比较通俗易懂!

分布式事务

(编辑:衡阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读