Java帝國之宮廷內斗

kinghitomi 7年前發布 | 28K 次閱讀 數據庫 JDBC 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大臣得意地笑了......

 

來自:http://zhuanlan.51cto.com/art/201708/548219.htm

 

 本文由用戶 kinghitomi 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!