分布式事务
现在遇到了几个项目,这些项目都有一个共同特点,就是要求分布式事务。能够满足跨系统的保持数据的一致性。举个简单例子,我没钱买房,问老婆借了1万块,到期了,该还给老婆了,那就转账吧。如图:
我的银行卡是招商银行的,老婆的银行卡是中国银行的,很显然这就是个分布式事务了,招行要完成的动作是A(我的账号)-10000, 中行的动作时B+10000,两个动作比如同时成功才OK,如图。
上网查了一下,这种分布式事务是有个开放协议的叫x/open,主要采用了两部提交法算法,异构的数据库只要实现了这个协议,就可以完成分布式事务。这个需要底层数据库的支持,因为这个协议和数据库底层实现密切配合,需要各个数据库的厂商自己完成符合xa协议的数据库驱动,即driver.
很多银行采用Tuxedo中间件来控制分布式事务,其实这个x/open协议就是由 tuxedo的xa协议来的。
那么这种分布式的事务结构,往往都是借助第三者的,架构图如下:
有意思的是这个x/open协议的实质,是叫做什么两步提交。
第一步叫做预提交。即多个系统事务“几乎”已经全部做好了,各个数据库资源告诉事务管理器--“i am ready",
事务管理器最后一声令下---“提交”,两者真正提交,提交过程中出错,全部回滚。
如果我们不知道有什么xa协议,两步提交,肯定有人会想,我自己写个中间件来搞个逆向事务不可以吗?这主要涉及到 01,10这两种case, 01表示我A-10000的事务失败,老婆的B+10000成功。那么我先反推导出,老婆的逆事务为B-10000,我的逆事务为A+10000. 那么如果老婆的事务成功,我的失败,很显然,老婆的事务要回退,那么就再执行个逆事务,B-10000.貌似有道理,但是这个逆事务的“推理机”你会做吗?似乎有难度哦。而且有问题的是,如果这个逆事务中途出现失败该如何处理,逆事务的效率如何等等。这都是一堆的问题。
这个分布式事务最大的缺点就是会锁定数据库资源,两步提交消息反反复复,对网络不好的情况,肯定很难有扩展性。于是有人提出了基于消息队列的分布式事务处理。有这篇文章。
这篇文章的关键代码就是这段,我看的有些稀里糊涂,说说自己的理解吧。
begin; INSERT INTO transaction VALUES(xid, $seller_id, $buyer_id, $amount); put_to_queue “update user(“seller”, $seller_id, amount); put_to_queue “update user(“buyer”, $buyer_id, amount); commit; for each message in queue begin; SELECT count(*) as cnt FROM message_applied WHERE msg_id = message.id; if cnt = 0 then if message.type = “seller” then UPDATE user SET amt_sold = amt_sold + message.amount WHERE id = message.user_id; else UPDATE user SET amt_bought = amt_bought + message.amount WHERE id = message.user_id; end INSERT INTO message_applied VALUES(message.id); end commit; if 上述事务成功 dequeue message DELETE FROM message_applied WHERE msg_id = message.id; end end
这段代码的场景是 A数据有一个交易的表transaction, B数据有个表User. 要求同时更新 transaction, user表。
那这段代码的意思是在数据库A上,开始一个事物,插入transaction表,并且把更新数据库B的消息放到了消息队列里。 在另一端的数据库里面,从消息队列里面获取消息,然后开启一个事务,根据消息做动作,然后用另外一个表(message_applied)做了一个log, 表明这个消息已经用过了。然后把消息队列中的消息删除,删除message_appied中的log.
文章最后这样保持了弱一致性。可能看到这里,你和我一样困惑。
还是上图那4中case:
00---(A 数据库操作失败,B数据库操作失败)
01---(A 数据库操作失败,B数据库操作成功)
10---(A 数据库操作成功,B数据库操作失败)
11---(A 数据库操作成功,B数据库操作成功)
begin;
INSERT INTO transaction VALUES(xid, $seller_id, $buyer_id, $amount); put_to_queue “update user(“seller”, $seller_id, amount); put_to_queue “update user(“buyer”, $buyer_id, amount); commit;
这段代码,我觉得应该加一个约束,就是 添加队列也应该在这个事务中,让其保持执行顺序的偏序,就是先插 transaction,然后 put_to_queue。因为有可能如果put_to_queue是个应用程序的话,很可能是先put_to_queue,然后插transaction,这样会导致01这种case出现,那么就会产生不一致性。(放进队列成功,但是插入由于unique的限制失败了)。如果能保证有这个顺序性,那么00,01这种case就不会出现.
那我们大胆假设这个消息队列也是数据库中的一个id自增的表。那么10这种情况会不会出现呢?也不会!根据单个数据库事务一致性。那么最后只剩下11这种case了。
后面的代码,就是A机器的队列传到B,B根据队列中的数据来执行动作。其实我们分析一下,A和B之间的队列的传输本身就存在不一致风险,断电了怎么办,队列中中数据没了,但是A数据库数据已经提交了,怎么办?所以文章说实现了弱一致性,这里面只不过玩了个风险置换的游戏,如果这种风险发生的概率很高,很显然这是不可取的。
这段代码的核心思想摈弃(00,01,10这3种case, 只留11z这种case)就是A数据库成功,那么操作数据库B的操作我通过消息队列或者其他备份措施,使其能够正确到达B机器,B机器也能百分之百完成,那么数据就满足一致性! 恰恰,这还是有风险的,我们需要找到一种机制让这种风险不存在,或者无限小。
谁能告诉我?!其实一段数据从A机器转移到B机器,通过某种协议还是100%做到的!不过这个协议应该有些复杂。所以文章最后说,如果项目时间短,还是用xa协议,分布式事务处理,如果不急,就可以采用消息队列,而且开发这个消息队列还是有些复杂的。
最后,如果不是数据库之间的数据一致,那又改如何处理呢?
为什么说若一致性呢,因为10这种情况也是能出现的,A数据库提交成功,B提交不成功(由于字段的unique限制等,二步提交法,第一步就会去跑一边事务,如果能跑,就进入第二步,如果不能跑,就通知两机器撤销事务)那么,很显然,我们明显是可以预料B数据库的事务是可以“百分百完成的”。那么这个思想,就是把单机的事务控制,比用利用log, 然后转移log,到B机去执行log,不过这种思想还是有欠缺的。
相关推荐
本文来自于csdn,本文主要从分布式的原因,事务特性,和解决方案中深入理解了分布式事务,希望对您的学习有所帮助。 分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的...
分布式事务是一个绕不过去的挑战!微服务架构本质上就是分布式服务化架构,微服务架构的流行,让分布式事务问题日益突出!尤其是在订单业务、资金业务等系统核心业务流程中,一定要有可靠的分布式事务解决方案来保证...
微服务架构的分布式事务处理方案
java分布式事务demo
这篇文章将介绍什么是分布式事务,分布式事务解决什么问题,对 分布式事务实现的难点,解决思路,不同场景下方案的选择,通过图解的方式进行梳理、总结和比较。相信耐心看完这篇文章,谈到分布式事务,不再只是有“2...
最全分布式事务视频课程详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 视频课程大纲: 1.事务基本概念讲解(本地、分布式) 2.分布式事务理论(CAP、BASE) 3.分布式事务解决方案之2PC(xa、...
介绍分布式事务的定义、原则和实现原则,介绍使用Spring框架实现分布式事务的几种方式,包括使用JTA、Spring事务同步、链式事务等,并通过实战介绍其实现。除此以外还介绍了一些分布式事务相关的技术,如幂等性、...
深入理解分布式事务
这就涉及到到了分布式事务,用需要操作的资源位于多个资源服务器上,而应用需要保证对于多个资源服务器的数据的操作,要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同资源服务器的数据一致性。...
详细讲解了通过消息来解决分布式事务的问题
例子虽小,可覆盖面广,设计spring载入.properties文件,spring配置jta和jotm分布式事务,设置数据源连接池,注解事务驱动。功能是在mysql上建立了两个数据库分别为dbone和dbtwo,在dbone里有表tb1,表中只有一个字段...
分布式事务ppt
自己封装redisson方法,同时通过注解的方式加入redis分布式事务锁,可靠。
分布式事务服务 (Distributed Transaction Service, DTS) 是一个分布式事务框架,用来保障在大规模分布式环境下事务的最终一致性。DTS 从架构上分为 dts-core 、dts-schedule、 dts-server 两部分,dts-core是一个...
为了实现分布式事务,需要使用下面将介绍的两阶段提交协议。 * 阶段一:开始向事务涉及到的全部资源发送提交前信息。此时,事务涉及到的资源还有最后一次机会来异常结束事务。如果任意一个资源决定异常结束事务,则...
实现系统对多数据源的操作。 实现系统对多数据源的分布式事务管理,包括事务的提交和回滚。
微服务架构的分布式事务解决方案,完整31讲。,百度云资源 非加密,无密码,
分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于...
1、详细介绍了Seata阿里分布式事务中间件; 2、对整个分布式事务解决方案原理进行了详细的分析,包括tcc、xa、saga等解决方案 3、IT老齐老师视频资料配套pdf;
基于若依项目改造的多模块分布式事务,使用了atomikos进行分布式事务的管理。