Java帝国之分布式事务解决方案

1 前情提要

上回说到IO大臣一直被JDBC大臣打压, 为了搞掉JDBC大臣, 他忍辱负重、历经千辛万苦终于搞出了分布式事务的标准Java Transaction API, 满心以为这次必定翻身,但是没想到国王为了平衡朝中的权利, 居然把JTA的管理权赐给了新任的JTA大臣。

更没有想到的是,幸亏自己没有管理JTA,这个官方标准太强调强一致性,和民间的高并发系统要求的最终一致性不合拍,用不起来,变成了JTA大臣的烫手山芋。

和民间代表深谈了一次以后,本来已经心灰意冷的 IO大臣再次激起了雄心壮志: 一定要把JDBC大臣和JTA大臣搞掉。

2 基本可用

IO大臣马上找了自己的心腹幕僚 InputReader , 交代了一项任务, 去民间考察这些高并发系统是怎么折腾最终一致性的。

InputReader 连夜出发, 为了不引起JDBC大臣和JTA大臣的注意, 这次特意微服私访。

他不辞辛苦, 跑遍了帝国大大小小几十个高并发系统, 与大量的民间领袖深入地交换了意见。 他越谈越惊心: 我们总是高高在上地制定所谓官方标准,自我感觉良好,实际上根本没人用, 前有EJB, 今有JTA, 都是脱离了实际需求想出来的。

3个月后, InputReader 已经成竹在胸, 回到京城向大人汇报。

“大人, 据小人观察, 我们的JTA用的人确实很少,我现在是理解了他们民间所说的最终一致性了”

看着黑瘦的InputReader, IO大臣心里非常感动, 暗下决心: 等老夫控制了朝局, 一定给忠于自己的InputReader升两级。

“还是拿那个转账的例子来说吧” InputReader 喝了口茶继续说 “ 假设两个账户(吕秀才和郭芙蓉)在两个独立的数据库中, 我们原来设计的JTA是要求从吕秀才账户减去100两银子, 然后在郭芙蓉账户加上100两银子, 这两个操作要么全部做完,要么全部不做, 但是在网络的环境下, 这是不大容易做到的, 或者说在高并发的情况下做到的代价太高。”

“这我理解,上次说了, 你说说民间到底是怎么实现的。” IO大臣有点心急。

“其实特别简单, 他们用了一个叫做消息队列的东西来实现的, 大人请看 ” InputReader 展开了一张图:

image

(码农翻身注: 消息队列的故事参见《Java 帝国之消息队列》)

IO大臣看着图: “就这么简单?”

InputReader 说: “小人举的是个非常简单的例子, 但是也能说明问题了, 你看我们想从吕秀才账户转100两银子给郭芙蓉, 需要在数据库1发起一个事务, 从吕秀才账户扣除100两, 然后还得向消息队列插入一条给郭芙蓉账号增加100两的消息, 然后这个数据库1的事务就结束了! 消息队列中的消息会在某一刻被读取出来,进行处理,给郭芙蓉的账号增加100两。”

“那给郭芙蓉添加100两的消息什么时候会被处理呢? ”

“这个时间不确定, 就看具体怎么实现了, 比如有个后台程序定期运行,读取消息来处理 ”

“那万一消息队列down机怎么办? ”

“不用怕, 消息队列的数据都是持久化到硬盘上的, 不会丢失。”

“郭芙蓉这么刁蛮, 这100两银子不能立刻到账, 她还不把吕秀才给‘排山倒海’了?”

“大人,这就是关键了,你想啊, 假设数据库2 down机了, 对郭芙蓉有两种选择: 一种是由于系统原因,转账操作完全不能操作,另外一种是可以转账,但是钱稍后到账,你说郭芙蓉会选哪一种?”

IO大臣说: “有道理,第一种情况是完全不可用, 第二种只是是部分可用, 郭芙蓉肯定会先让吕秀才转账, 反正100两银子是自己的, 早一点晚一点也没关系。 ”

“对的, 这就是最终一致性,数据虽然在某些时候看起来不一致,吕秀才的钱少了但是郭芙蓉的钱没增加,这个时候钱在消息队列中暂时存着呢。”

“这样做有什么好处?”

“好处很大,对于高并发的场景,转账的时候扣完钱, 向消息队列插入消息,事务就结束了, 根本不用什么两阶段提交, 性能很好。”

“嗯,不错, 我们再来看看一些细节吧。。。。。。”

3 走漏风声

天下没有不透风的墙, JDBC大臣的密探早已潜伏在IO府中好多年了,虽然只是个端茶送水的下人, 但是很多消息都进入了他的耳朵, 然后又进入了JDBC大臣的耳朵。

JDBC大臣找来了JTA大臣前来商议, 为了找一个同盟军和强大的IO大臣对抗, JDBC大臣收买了不干实事的JTA大臣。

“你知道吗? IO老头儿派人出去调查了, 我估计很快就会像上次那样参我一本。” JDBC大臣忧心忡忡。

“这IO老头儿为啥老是和大人过不去呢, 守好他那一亩三分地多好!”

“人的欲望都是无穷的,再说我这几年确实打压他比较厉害, 不说了,你先看看这张图, 是我们的卧底从IO府中偷出来的。”

JTA大臣抽了一口冷气:“现在民间都这么玩了? 不用JTA了? ”

“是啊, 你看他们的方法还不错嘛, 基本可用,最终一致性。真是实践中出真知啊” JDBC大臣感叹道,他在观察JTA的反应。

“大人, 我建议咱们抢先一步, 明天早朝就把这幅图献给陛下,陛下一高兴,估计就会把这一块儿划给我管了, 不不, 是给你管了。 ”

“这合适吗?”

“无毒不丈夫, 朝中争斗本来就是你死我活的, 大人不可太妇人之心了。”

“好,就这么办。”

4 宫廷激辩

国王已经厌倦了早朝, 厌倦了臣子们在朝中争来争去。

这天出奇的平静, JDBC大臣和IO大臣没有像之前那样争得不可开交, 国王正要宣布 “有事启奏,无事退朝” , 一直以来战战兢兢的JTA大臣咳嗽了一声, 发言了 :

“陛下,臣最近得到一个民间上供的设计图,说是民间用了一种新型办法来处理高并发问题 ” JTA 一边把偷来的图纸呈上去,一边用余光迅速地扫了一眼IO大臣。

JDBC在一旁添油加火:“陛下,臣也看过这个设计, 觉得非常不错, 建议帝国设立标准推广。”

IO大臣一切都明白了,自己还没有出手,这俩老头儿先下手为强了。

国王自然是看不懂,听到两位大臣都这么肯定, 懒洋洋的说: “爱卿此言不错,这个既然属于分布式事务, JTA大臣,你来领衔把他设计出来。”

IO大臣看准时机,突然出手:“陛下万万不可, 这个设计有重大缺陷啊!”

“什么缺陷? ” JDBC大臣和IO大臣齐声问道。

IO大臣胸有成竹, 一切尽在计划之中,那个图纸只不过是个小诱饵而已,这两个愚蠢的老头儿果然上钩。

“陛下,请看这个图纸, 吕秀才给郭芙蓉转账的时候,图纸中写的是:”

image
image

“我想请问JDBC老头儿, 不, 大臣, 这个事务同时操作了数据库和一个消息队列, 这两个东西是完全不同的, 请问你是怎么实现的?不会还是使用老掉牙的JTA吧”

(码农翻身注: JTA不仅仅可以支持数据库, 只要是支持XA协议的数据源都可以)

JDBC心中大叫不好,中计了! 唉,自己怎么不仔细研究下图纸呢, 这么一个缺陷竟然没有发现, 冒冒失失地献给陛下,真是不可饶恕啊!

可是他不甘心就此失败, 稍一定神,立刻反击: “先不说缺陷问题, 我想问你这个图纸刚才只有陛下看了, 你怎么知道其中内容?!”

IO大臣看到他反咬一口,岂能罢休 ,一不做二不休,干脆撕破脸: “陛下, 这张图纸本来是我府中的InputReader 走遍帝国,遍访民间疾苦画出来的, 我们知道有缺陷, 还没来得及修改,就被他俩给偷了去 !”

“你血口喷人!” JDBC和JTA有些心虚了。

“陛下,我已经抓住了偷窃图纸的佣人, 随时可以传唤。”

国王一切都明白了: 这些大臣之间的争斗真是无处不在啊, 每天如此,都不能让我消停一天。

“爱卿,” 国王对IO大臣说, “你先说说怎么解决那个图纸中的缺陷问题吧”

“陛下,其实有很多办法, 比如这一种” IO大臣从袖中掏出一个图纸,举了起来,让大家都能看到:

image
image

“在这里,我们可以添加一个‘事件表’, 转账开始的时候,把吕秀才的100两银子扣除, 同时还向事件表插入一行记录: 需要向郭芙蓉转100两, 由于这两个表是在同一个数据库中,所以直接使用本地事务就行。不用什么分布式事务。”

“你那个定时运行程序干嘛?” JTA大臣理解力有限

“就是定时运行, 从事件表中取出记录, 向MQ写入消息, 然后把记录的状态改成‘DONE’, 这样下次就不用再去取去处理了。 ”

JDBC大臣很老练: “那你这个定时运行程序也有问题啊, 比如说它读了数据,向消息队列写入了消息, 还没来得及把事件表的status 改为 ‘DONE’ 就崩溃了,等到定时运行程序重启以后,岂不再次读取, 再次向MQ写入消息,这样郭芙蓉不就得到了200两银子,整个系统就不一致了。”

IO大臣心里有点佩服, 这老头儿还是有两把刷子的。 幸亏我和InputReader讨论过各种细节,要不然还真被他给问住, 那在陛下面前就悲催了。

5 幂等性

“其实这里必须得引入一个概念: 幂等性” IO大臣说

“迷瞪性? 这是什么东西 ” JTA大臣大惑不解。

“是幂等性, mi ,四声” IO大臣对朝中有这样不学无术占据高位的家伙感到很悲哀, “这个幂等性说的是当你对一个事物操作的时候,可以一直重复地操作,那个事物不受影响, 例如对郭芙蓉的账号你查询一千次,一万次,账户余额还是那么多,不会变化。 转账操作就不是一个幂等性操作。 每次操作都会导致账号的变化。”

JDBC大臣也不由地鄙视了下JTA老头儿, 他说:“我明白了,你的意思是说那个定时运行的程序可以出错,可以向消息队列写入多次 ‘给郭芙蓉账号增加100两银子’ 这样的消息, 但是郭芙蓉那边在执行的时候, 肯定也要判断之前是否执行过了, 如果没有的话就增加, 如果执行过了就简单的抛弃这个消息即可。 ”

IO大臣向JDBC大臣投去了佩服的目光, 两人目光相遇, 碰出来了惺惺相惜的火花。

“唉, 我要是早点和JDBC/IO大臣合作多好” 两个人都在暗自吃后悔药。

IO大臣说: “是的, 郭芙蓉那边在判断是否已经执行过的时候,也需要查询之前的执行记录, 这就意味着之前执行过的也需要用一个表保存下来才行。”

“众位爱卿, 看来已经讨论得差不多了, 接下来怎么办啊?”

没人出声。

“那要不这样, 既然是民间先做出来的东西, 我们官方就不用去凑热闹了, 让他们自生自灭吧” 国王祭出了“无为而治” 的大法, 其实他实在不想再调停这几个大臣之间的争斗了。

IO大臣想发言却又忍住了,经过这一番较量, 他看清楚了各位大臣的实力, 也理解了国王的苦衷, 如果再这么争斗下去陛下估计会龙颜大怒, 算了,不争了。

傻傻的JTA大臣还不死心, 一直给JDBC大臣使眼色,只是JDBC大臣心中打定了和IO大臣一样的主意,微闭双眼开始养神了。

IO大臣心情平静地回到家中, 幕僚们围上来询问结果, 他们还做着升官发财的美梦。

IO大臣看着这些急于知道结果而显得特别饥渴的表情, 笑着摆了摆手, 一言不发地离开了。

很久以后,朝中得知民间有个叫做Dan Pritchet的人, 把这种方法总结了一下,称之为BASE模型, 从此流行开来。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容