WebService的事务处理 (转)
因為這個問題討論起來內容比較多一些,所以另開一個話題。
?
??? 如果你只是要解決兩個系統之間的事務同步問題,可以采用判斷服務是否成功的辦法來解決,即:
???
??? * A系統開始自己的事務,處理自己的數據,然后。。。
??? * 在提交之前調用B系統的服務。
??? * B系統開始自己的事務B,在事務中處理數據,再提交事務。
??? * B系統把自己事務的提交成功與否的信息做為返回值回饋A系統。
??? * A系統根據B的事務成功情況決定自己的事務是否提交或是回滾。
?
??? 但是,在繼續深入討論這個問題之前,先反問一個引伸的問題:當分布式系統之間,要進行事務控制的子系統不是兩個,而是N個時,如果進行事務控制?
?
??? 分布式事務一直都是很難解決的問題。在面向DCOM的分布式應用中,有一種分布帶事務支持策略,大體的思路是采用兩段式事務提交的辦法,第一次提交是預提 交,預提交之后是可以回滾的。第二次提交是永久性的提交,提交之后就不可以回滾。并且,如果預提交成功,第二次提交也必然成功,系統必須可以保證這一點。
?
??? 這樣,當每個系統都支持這種兩段式提交之后,就可以采用這樣的事務管理:一個控制角色向每個分布系統提出執行要求,并要求完成第一次事務提交。當每個系統 的第一次提交都成功時,則要求所有系統完成最后的永久提交,可知這次的永久提交是肯定可以完成的,因此不須要再擔心這次提交是否成功。
??? 如果第一次提交中,有某些應用出現失敗,則要求所有的應用都回滾事務。
??? 一些數據庫軟件本身就支持事務嵌套,如sqlserver等,不幸的是,我們的主力數據庫informix不支持。
??? 為了簡化這種分布式事務管理,有一些中間件產品可以采用,用得比較廣泛的是MS DTS.
?
??? 你可能已經看出來了,這樣的事務控制策略雖然可以在分布式環境下滿足事務的ACID要求,但是它對各個分布組件是有要求的,在基于COM, remoting,JRMI一類技術的分布式應用程序中,這個沒有問題。但是在采用web service的場景中,這是有問題的。
?
??? 問題1. web service是一種以松耦合為指導思想的集成方式,一般情況下,主張采用無狀態方法。
??? webservice主張兩次調用之間沒有上下文關系,即一次調用與其他之前和之后的調用都沒有關系,一次提交即完成一次完整的處理。但是分布式事務卻要 求各方要在兩次對話之間保持對話狀態,以便于知道本次永久性提交時,要對之前“哪一個”已經被預提交成功的事務執行最后的提交。
??? 當遇到這個問題時,我們必須要再多問自己一個問題:我們已經選擇了正確的集成技術嗎?如果多個系統之間有如此緊密的事務耦合關系時,我很懷疑它們其實就是 同一個應用系統。同一個應用系統中,應該有相同的平臺,相同的進程空間,相同的數據模型以及數據源。這種情況下,采用web service是一種錯誤的選擇,web service應該用于不同平臺、不同應用、不同的數據模型的系統集成。即便是的確需要在同一個應用系統中由于某些原因而實現模塊間的分布式構造,也應該 采用同一技術平臺內的遠過程訪問技術,它們能通常比web service能提供更好的耦合性支持。
?
??? 好吧,假設你經過思考之后,對上述問題的回答是“是”:我們確實必須要在異構的、多平臺的、本來應該是低耦合系統之間實現分布式事務控制。那么,webservice還有用處嗎?
??? 謝天謝地,web service雖然主張交互之間采無狀態方式,但是它并不是禁止采用有狀態的交互。WEB SERVICE還是一種web技術,而web技術中的狀態保存可能是最早被解決的問題之一了。在所有的web開發技術平臺中,都有session機制,無 論這些Session是通過IP,cookies, hidden input來實現,還是url sessionid來實現的,反正都有辦法實現,請參閱所用平臺的session支持機制就可以了。退一萬步,你也可以通過在服務器中維護一個應用程序級 的事務池來實現,未最后提交的事務對象都放在里面,每一個事務對象都給定一個唯一個的標志ID來識別,形成一個字典對象池。如果啟動事務成功,則把此事務 的ID返回給調用者執有,做第二段提交時,把事務的ID做為參數提交就是了。(隨便提一下,用這種方法時,千萬不能把對象的指針、句柄、引用什么的平臺相 關的值交給客戶方,倒不是害怕安全問題,而是這些值在分布系統中是沒有意義的,上次返回的指針沒準早被垃圾收集機挪到其他地方去了)
?
??? 無論如何,webservice在通信層上是一種無連接的協議,每兩次調用之間,tcp連接是斷開的,因此,一但采用session機制來管理上下文,你 就必須為這些session的生命期負責。試想,如果一個事務上下文已經開啟,而此時客戶方系統卻突然當機了,這時會出什么事情?在同一個應用程序域中, 客戶方的當機會讓連接中斷,服務器立即就會中斷并回退事務,但是在webservice里,狀態管理機無法立即感覺到此事務的調用方已經失去控制,只能在 一定的時間之后,才發現:“噫?這個事務已經N長時間沒有人訪問了!快快回退!”在ASP.net里,默認的狀態超時時長大概是20分鐘,JSP也差不 多,阻塞了20分鐘的事務對數據源是什么影響可想而止!因此,必須考慮合適的狀態時長與事務隔離級別,以減小對數據源的性能影響。??????
?
??? 問題2. web service的“反模式”方法論使得無法在系統之間統一出共同的抽象接口。
??? web service是一種“反模式”的系統架構思想,即不是一般的由先建模并抽象接口開始,再由各個分布系統實現接口的系統構造方式,而是反過來:系統可能早 已經完成,現在的問題是兩個系統間的信息交互作用,因此交互的接口規格是根據需要,把系統數據模型去范式化后挑挑撿撿而定的。
??? 因此,webservice中不支持接口抽象,即:你無法定義一個各個系統都必須實現的抽象事務接口,然后由各個系統實現這個接口的多態,最后在承擔事務 控制器的應用中調用統一事務接口以調度分布事務。雖然這樣的接口模型在很多面向對象的開發平臺中的遠過程調用技術中所支持,但是如同之前說過的,web service是一種用于集成的松耦合的反模式方法論,而不是為緊耦合系統中的分布式對象而設計的。
??? 所以,雖然有點討人煩,但是我又一次忍不住想問我已經問過的那個問題:我們真得用對了技術嗎?如果多個系統之間需要如此級別的接口耦合性,我真得越來越懷疑它們其實就是同一個應用系統了。
??? 假設你的回答還是“是,他們真得不是同一個系統,他們是異構平臺的,異構數據的!”好吧,那么繼續。讓我們采用web service來完成集成,但是你必須忘記你的OOP思想,老老實實地編碼,用枯燥的、重復的代碼把所有的系統的事務都控制在一起,別想用對象抽象的概念 來省一點事。
??? 真的嗎?
??? 如果把事務控制器獨立出來如何?假設我們建立一個專用于分布式服務控制的應用,而用WEB SERVICE的方式公布接口, 允許其他應用程序通過向這個事務控制器注冊自己的兩段式事務開啟、提交和回退的web service接口。然后,當有客戶想啟動分布事務時,就可以向這個事務控制器發起分布式事務請求,選擇事務各方,啟動一個分布式,最后向事務控制器,而 非是各個事務方直接發起提交請求,這樣事務控制的多態就可以在事務控制服務器中實現,雖然實現可能還是通過查表等方式實現,而非平臺級的抽象方法,但是對 于事務客戶來講,這樣一個服務器就是多態的實現部分。
??? 如果真得比MS更快更好地實現這樣一個web service做接口,面向異構系統的分布式事務控制器,NASDAQ也許會有你的一席之地吧!
?
??? 問題3. 異構平臺不一定都支持兩段事務提交模式。
??? web service面向的是完全異構平臺的集成,那么顯然不能指望每個平臺都能支持兩段時提交事務模式。但是,標準就是標準,協議就是協議,標準就是用來讓大 家遵守的,如果一個平臺本來不支持兩段式事務,那么為了能支持分布式事務,它就必須改造以實現兩段式事務提交。
??? 怎么改造是各個應用系統內部的事情,為了本文討論的全整性,也在這里稍微涉及一下。
??? 首選的方式是通過數據緩存的方式來實現。很多OO系統中,都采用了所謂的N層架構,即把業務對象與關系表模型分離開來,業務對象位于系統內存或是緩存中, 由運行時的對象容器管理,容器根據一定的策略,把緩存中業務對象向數據庫這樣的久永介質中保存,或是從數據庫中加載所需要的業務對象,在保存和加載過程 中,將完成對象到表數據的轉換,或是相反。
??? 一般的N層結構的中間件產品中,都會提供兩個級別的事務,即面向緩存中對象的事務控制和面向持久化過程的事務,可以考慮簡單地將此兩個事務級別對應的分布 事務中的兩段事務提交。但是,這種方式必須冒一定的風險,如對象容器級的事務成功,而數據庫事務提交時出現失敗,此時將會導致的數據不一致的風險,盡管這 個幾率并不很大。
??? 在使用數據容器的情況下,也可以用保存對象的歷史狀態來實現事務的手工回退。因為在業務對象層與持久化層相分離之后,持久化層在數據更新時并沒有復雜的邏 輯,只是一些被羅列的、業務意義無關的數據更新序列。如果可以保持對象的狀態歷史,那么就可以在需要的時候將對象的狀態恢復到舊的舊版上。實際上,在一些 出色的中間件平臺中,這個機制已經實現得非常完善了。(可以參閱Graphtalk平臺的對象持久化管理,簡直是天才!)
??? 另一種笨辦法是通過數據邏輯來實現兩段事務提交,例如在要求第一次提交時,即真正提交,在第二次提交時固定什么也不做,而返回正常。如果要求回退,那么就通過數據邏輯或是業務邏輯來更新數據為舊狀態。這種實現方式絕對是很令人頭痛的。
??? 不過,幸虧我們不是在為一個通用的數據庫設計兩段事務機制。要知道,面向服務的事務處理并不是如同數據庫級別的事務那樣,在事務的期間數據的操作有無窮的 可能性。通常我們一個服務就是一個功能,其數據操作過程中,數據的變化方式是可預知的,因此恢復數據的狀態也是一個個具體而固定的過程,只要我們針對每一 個服務操作設計數據恢復機能就是了。
??? 最后,如果這些都不可能實現的話——大于50%的可能性,因為時間、成本、技術等原因,這些都實現不了,那么只能靠兩個字了:妥協。
轉載于:https://www.cnblogs.com/keitho00/p/4315207.html
總結
以上是生活随笔為你收集整理的WebService的事务处理 (转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开源android豆瓣电影阅读器
- 下一篇: 页码导航算法