- 大话编程
- 一个故事讲完 https
- C 老头和 Java 小子的硬盘夜话
- 我是一个函数
- 操作系统是个大骗子?
- 90 后 老头儿 和 00 后 Go 小子的硬盘夜话
- 爱炫耀的数据库老头儿
- 浏览器:一个家族的奋斗
- 浏览器家族的安全反击战
- 黑客三兄弟
- 从读写分离到 CQRS,张大胖是如何解决性能问题的?
- 两个程序的爱情故事
- 两个程序的爱情故事(续)
- 烂代码传奇
- 机房夜话
- 干掉状态:从 session 到 token
- 张大胖的 docker 之路
- 从 SOA 到微服务
- XML 的传奇人生
- 从密码到 token, 一个授权的故事
- 编程世界的那把锁
- 加锁还是不加锁,这是一个问题
- 这个动物园, 两年也逛不完
- 张大胖和 CAP 定理
- 一个翻译家族的发家史
- 张大胖和单元测试
- Java 帝国
- 一个著名的日志系统是怎么设计出来的?
- Java 帝国之泛型
- Java 帝国之动态代理
- 从兄弟到父子:动态代理在民间是怎么玩的?
- Java 注解是怎么成功上位的?
- Java EE 要死掉了?
- Java 帝国之宫廷内斗
- Java 帝国之宫廷内斗(2)
- 当世界上只剩下一个 Java 程序员
- 持久化:Java 帝国反击战
- 什么是框架?
- 学习 Java 虚拟机没用? 听听当事人是怎么说的!
- 聊聊 Java 平台上的非 Java 语言
- Java 帝国之消息队列
- Java 帝国之 JMS 的诞生
- Java 帝国之单例设计模式
- 对 Java Inputstream 的一次采访
- ASM: 一个低调成功者的自述
- 序列化: 一个老家伙的咸鱼翻身
- Java IO 的自述
- JDK 先生最近有点烦
- 什么是框架(续)?
- 说 空话,做实事: 谈谈多态
- Kotlin 初体验
- 小白科普
- 小白科普:分布式和集群
- 什么是 Zookeeper?
- 小白科普:悲观锁和乐观锁
- 小白科普:LDAP 有什么用?
- 小白科普:服务那点事儿
- 小白科普:Netty 有什么用?
- 老司机经验
- 后端程序员都做些什么?
- 为什么要学习 HashMap 的底层原理?
- 小心,别被今日头条给困住了!
- 对自己狠一点,开始写作吧
- 开源代码啃不动,不如先定个小目标
- Python 这么简单还用学吗?
- 作为一个有追求的程序员,你应该掌握的七种武器
- 给设计模式说句公道话
- 时间是这么被浪费掉的
- 你真正付出了全部努力了吗?
- 写给初学者:编程的本质
- 在大学期间更应该学习什么?
- 看看 悲催 的码农得学多少东西?
- 学习编程的四兄弟
- 那些年,我后悔没做好的事情
- 我为什么对后端编程情有独钟?
- 当我们在学习编程语言时,我们在学习什么?
- 编程需要多少数学知识?
- 想成为编程高手,一定要学汇编吗?
- 你必须理解的计算机核心概念
- 你的需求是怎么描述的?
- 白话敏捷软件开发
- 人在职场
- 凡事必先骑上虎背,给性格内向的程序员聊几句
- 为什么能力优秀的人当了主管以后反而不行了呢?
- 不想做技术了,还有一条路
- 纪念我最有效率的一次加班
- 书写「简历」时,需要规避的错误。
- 上天还是入地?
- 工作 6 年,半路出家到 CTO
- 只是 Work 还不够,更重要的是 Think
- 我所尊敬的三位女程序员
- 我们向印度人学习什么?
- 你去下家面试,怎么评价你在这家公司做的工作?
Java 帝国之宫廷内斗
1 JDBC 大臣
自从和东海之滨的数据库联合酋长国缔结了合作协议以后, IO 大臣就退居二线了。
他本来也想把 JDBC 也划归自己管理, 奈何国王头脑发热、竟然任命了新的 JDBC 大臣, 专门负责这一摊事儿。
JDBC 大臣经常在早朝上给国王吹风: “ 陛下, 我们的 JDBC 设计的非常好, 别看什么 Hibernate, Mybatis 是现在的事实标准, 他们底层都在用我们的 JDBC 接口。 ”
国王赞许地频频点头,似乎忘记了这是躲在角落中 IO 大臣的功绩。
IO 大臣咬牙切齿又无可奈何。
这天 JDBC 又在给国王安利关系数据库的好处: “陛下,这关系数据库相比于简单的文件系统有个巨大的好处,就是支持事务。”
听到 JDBC 大臣又在贬低自己负责的部门, IO 大臣怒火中烧。
国王问道:“什么是事务,要事务干嘛? ”
“我举个通俗的例子你就明白了, 假设 IO 大臣要给我转账 100 块钱, 他的数据库账户要扣掉 100 块, 我的账户要增加 100 块, 这就涉及到两个操作, 这两个操作要么全部完成,要么一个都不做,只有这样才能保证数据的一致性, 这就是一个事务。数据库联合酋长国有个对事务总结了 4 个特性: 原子性(Atomicity) ,一致性(Consistency), 隔离性(Isolation) , 持久性(Durability) , 简称 ACID, 要不我再给详细的解释下?”
国王连忙摆手:“不不不, 别拿这些细节烦我, 你就告诉我们的臣民怎么去使用就行了”
JDBC 大臣说: “这个很简单, 默认情况下我们的 JDBC 都会把对数据库的操作认为是一个事务, 当然臣民们也可以设置成手工的方式, 手工地提交和回滚事务。不管哪种方式,都是非常简单的 。”
国王说: “那就好, 爱卿辛苦了, 还有事吗? 有事启奏,无事退朝。”
2 密谋
IO 大臣回到家中,依然感觉火气难平, 招来幕僚商谈。
InputStream 说: “大人, 这 JDBC 大臣虽然猖狂, 我们却暂时拿他没办法, 现在都是 Web 时代, 哪个应用不用数据库啊? ”
“难道就让他这么猖獗下去? ”
InputReader 足智多谋: “我倒是有一计, 只是得等待时机。 ”
“什么时机?”
“你看今天 JDBC 那厮提到了事务, 但是这个事务只是在一个数据库中有用啊, 如果需要跨数据库怎么办? 比如我的账号存在数据库 A, 你的账号在数据库 B, 那转账的时候怎么办? 怎么实现什么 ACID ? ”
InputStream 表示不同意: “谁会这么傻, 把我们的账号信息放到两个数据库当中? ”
“这就是时候未到, 现在大部分的应用数据量都不大, 放到一个数据库中绰绰有余,等到数据量大到一定程度,势必要拆分数据库,就会出现跨数据库的事务, 到那个时候我们的机会就来了, 我们准备好解决方案, 参那厮一本, 不信扳不倒他!”
IO 大臣拍板: “好! 就这么办, 这事离不开数联酋(数据库联合酋长国)的支持,我和他们还有交情, 这就派人去,许以重金, 让他们继续和我们合作。”
在 IO 大臣密谋的同时, JDBC 大臣的家中却是觥筹交错、莺歌燕舞。
有识之士如 Connection 曾经向 JDBC 大臣提醒过要和数联酋搞好关系, 以便将来有什么不时之需。 可是处于巅峰的 JDBC 大臣哪能听得进去?
3 两阶段提交
InputReader 果然很有远见, 随着时间的流逝, Web 越来越发达, 帝国出现了很多巨型网站, 他们的各种数据果然是没法放到一个数据库中了,把大的业务系统查分成多个数据库势在必行, 当一个业务同时操作多个数据库的时候, 没有分布式事务是做不了的。
正在此时,一个秘密奏章被送到了国王的案头, 状告 JDBC 大臣因循守旧,面对大好的形式不与时俱进,对分布式事务漠不关心,毫无作为。
国王召集朝会,讨论分布式事务的问题, 他向 JDBC 大臣率先发难: “爱卿, 你听说过臣民们要求支持分布式事务吗?”
JDBC 大臣慌了: “这。。。 这好像是一撮刁民提的要求吧, 陛下不用理会。”
IO 大臣冷笑一声:“刁民? 我看是良民吧 ! 启奏陛下, 据臣所知,帝国有不下百个系统要求支持分布式事务,JDBC 大臣竟然连最基本的情况都不知道, 真是毫无作为。”
IO 大臣觉得稳操胜券,直接撕破了脸。
国王心里明白了几分, 他直接对 IO 大臣说: “爱卿,你说说该怎么办?”
“陛下,当年臣和数据库联合酋长国谈判的时候, 和他们建立了良好的交情。 前几天我宴请他们的时候,特别提及了这件事情。 Oracle 告诉臣,这很好办, 人家别的王国正在讨论实施两阶段提交的协议, 我们也可以参与进来。”
虽然 IO 大臣已经和数据库联合酋长国讨价还价了很久, 不知道花费了多少金钱,但还是不显山不漏水、很随意地说了出来。
JDBC 大臣一看 IO 大臣进入了自己的一亩三分地, 急忙问道: 什么是两阶段提交?
IO 大臣不屑地瞥了他一眼, 从袖子中拿出早就准备好的提议,双手向国王奉上。
国王哪里看得懂,扫了一眼就赐给望眼欲穿的 JDBC 大臣, 只见上面赫然写着:
两阶段提交协议
由于涉及到多个分布式的数据库, 我们特设一个全局的事务管理器,它来负责协调各个数据库的事务提交, 为了实现分布式事务,特设两个阶段:
阶段 1: 全局的事务管理器向各个数据库发出准备消息。 各个数据库需要在本地把一切都准备好,执行操作,锁住资源, 记录 redo/undo 日志, 但是并不提交, 总而言之,要进入一个时刻准备提交或回滚的状态, 然后向全局事务管理器报告是否准备好了。
阶段 2: 如果所有的数据库都报告说准备好了, 那全局的事务管理器就下命令: 提交, 这时候各个数据库才真正提交 , 由于之前已经万事具备,只欠东风,只需要快速完成本地提交即可;
如果有任何一个数据库报告说没准备好, 事务管理器就下命令: 放弃, 这时候各个数据库要执行回滚操作, 并且释放各种在阶段 1 锁住的资源。
JDBC 大臣也是行家,一看就明白了是怎么回事。阶段 1 就是让大家都准备好,阶段 2 就是迅速提交。
这是一个看起来很美的理想方案,但是他意识到其中有漏洞,自己的幕僚曾经告诫过:一旦涉及到分布式,事情就不会那么简单,任何地方都有失败的可能。
比如在第二阶段,那个事务管理器要是出了问题怎么办? 人家各个数据库还在等着你发命令呢? 你迟迟不发命令,大家都阻塞在那里,不知所措,到底是提交呢?还是不提交呢, 我这里还锁着资源呢, 迟迟不能释放,多耽误事啊 !
还是第二阶段,事务管理器发出的提交命令由于网络问题,数据库1收到了,数据库2没收到,这两个数据库就处于不一致状态了, 该怎么处理?
JDBC 大臣决心给 IO 大臣挖个坑:让你逞能 ! 让你给老子穿小鞋!
他说:“ 陛下,IO 大臣不愧为设计过 JDBC 协议的股肱之臣, 臣才学疏浅,深为拜服,特奏请陛下恩准 IO 大臣再次出山和数据库联合酋长国设计出新协议, 来支持分布式事务。”
国王准奏。
4 JTA
IO 大臣满心狐疑, 不知道 JDBC 老头儿在给自己下什么药,回到府中和大家商量。
InputReader 眼看自己多年前的计策就要成功,颇为兴奋: “管它呢, 只要咱们把这个分布式事务的协议给制定好,JDBC 老儿就得下台了。”
“对,到时候我们就掌管文件, 网络,数据库,Java 帝国就是我们 IO 独大了” InputStream 开始畅想美好的未来,到时候自己估计至少从 5 品升为 4 品。
IO 大臣马上安排和数据库联合酋长国的谈判,由于之前良好的交情。 这一次协议很容易就达成了, IO 大臣给他起了一个很响亮的名字: Java Transaction API (简称 JTA)。
这个 JTA 规范用起来也比较简单, 只要获得一个 UserTransaction 就可以操作了,帝国的臣民们根本不用关系底层的协议细节:
经过国王的批准, JTA 正式推广。
可是令 IO 大臣万万没有想到的是, 国王在 JTA 发布的前夕, 亲切地召见了自己和另外一个不知名的官员, 国王关心地说:“爱卿,朕知道你很忙,掌管着网络和文件操作,为了给你减轻负担,朕决定任命一个新的 JTA 大臣来协助你!”
IO 大臣如同五雷轰顶,自己辛辛苦苦的工作完全被无视, 这到底是为什么?
他失魂落魄地回到府中, 好几天茶饭不思。
还是 InputReader 出来安慰了他: “这是陛下的帝王之术, 害怕我们一家坐大, 平衡了一下朝中力量。大人可以放宽心, 你看 JDBC 大臣也受到了打压,风光不再了。”
5 塞翁失马,焉知非福
JTA 并没有取得像 JDBC 那样的广泛应用, JDBC 大臣挖的那个坑现在终于露出了狰狞的面目。
只不过这个坑并没有让 IO 大臣掉进去, 新任的 JTA 大臣背了黑锅。
臣民的抗议声越来越多: 分布式事务伴随着大量节点的通信交换, 协调者要确定其他节点是否完成, 加上网络带来的超时,导致 JTA 性能低下, 在高并发和高性能的场景下举步维艰。
拜 IO 大臣的工作所赐, 现在数据库联合酋长国的各个部落都支持两阶段提交,很多应用服务器 Websphere , Weblogic 等都支持 JTA, 可是使用者确是寥寥无几, 都快成摆设了。
JTA 大臣每次上朝都战战兢兢, 他是个平庸之辈,虽然四处救火,但是无力解决根本的问题。
现在那些高并发的系统反而极力避免两阶段提交, 他们绕开 JTA 大臣, 直接找到了 IO 大臣诉苦:“大人,你带领着制定了 JTA, 但是这个标准太理想化,完全不符合实情啊! ”
IO 大臣说: “不会吧,这不是你们要求的吗, 用户 A 和 B 的账号分别在两个数据库, 当 A 给 B 转账 100 块的时候, 肯定得保证 A 扣掉 100, 然后 B 增加 100 啊。”
“这就是官府的想法, 总是想着让两个数据库保证实时的一致性(强一致性), 为了达到这个目标,JTA 付出的代价太高了。 我们现在不想这么干了。 我们可以忍受一段时间的不一致,只有最终一致就行。 比方说 A 给 B 转 100 元, A 中的钱已经扣除, 但是 B 中不会实时地增加,过段时间能保证增加就行了”
“最终一致性? 有点意思!” ,想到 Java 帝国的官方标准总是被臣民们所建立的事实标准所打败,敏锐的 IO 大臣立刻看到了背后的机遇, 他决定这一次要联合民间力量,再次反攻, 一举搞掉 JDBC 大臣和 JTA 大臣。
想到这里, IO 大臣得意地笑了......
(未完待续)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论