正如我們所知的,Web Service的SOAP消息可以通過許多種基于Internet的網絡傳輸協定來傳送。大部分情況下,我們使用HTTP協定來傳送SOAP消息,一個優勢是,由于HTTP協定的無狀态特性,那麼,基于其的SOAP消息很容易的穿過防火牆;但同時也有一個副作用就是,無法保證Web Service用戶端和服務端的一緻性,即Web Service事務不可控制。
我并不十分了解諸如SDO(Service Data Object)\SCA(Service Component Architecture)之類的新新技術規範模型是如何解決這個問題的,這裡我隻想提出一種基于Spring架構的解決思路,及實作。沒錯,正是利用Spring這種我們“JavaEE生活”中最大衆化的産品的事務管理機制,結合Apache最新的Web Service引擎Axis2,加以擴充實作的。
它可以在一定範圍内解決Web服務用戶端與服務端事務不可控制的問題,利用自定義政策補償出現異常情況的事務,以下給出解決JDBC和Hibernate資料持久化的Web Service事務問題的方案。
基本原理就是擴充Spring的JDBC及Hibernate事務管理架構(實際上就是分别繼承Spring的DataSourceTransactionManager和HibernateTransactionManager)。
Spring本身的管理方法是将本地事務控制在一個線程中,将事務資源(諸如Connection Holder之類)存儲在ThreadLocal,即本地線程綁定的變量中,以友善的在多個事務或事務的嵌套中“挂起”、“恢複”事務,目标是完成“整體”的事務。
現在,我們可以對其加以改造:在Web Service服務端執行完畢後,不立即送出事務,而是将本應放入ThreadLocal中的Spring事務資源放入一個“事務資源池”中(這個事務至少應該是線程安全的),那麼,這就相當于“挂起”在服務端的事務,然後,利用Axis2的異步Web Service用戶端的特性,去完成用戶端的事務先——執行異步用戶端回調方法中的用戶端事務,好,接下來将會有以下幾種情況出現:
用戶端事務送出成功——則用戶端會自動通知服務端送出“事務資源池”中相應的事務,兩方面事務成功送出。
用戶端事務送出失敗——無論是由于異常爆發或業務邏輯未通過,在這種情況下,用戶端都應通知服務端“復原”(rollback)事務,以保證兩端一緻性。
用戶端與服務端失去聯系——這種場景最常見的情況就是網絡瞬斷。那麼,由于接收不到用戶端的消息,服務端被“挂起”的事務就應該在指定的等待時間後,去觸發執行特定的“事務逾時”政策,根據配置的政策對失去聯系的服務端事務進行“補償”處理,這種處理表現為“復原”(rollback)或“送出”(commit)。
以上隻是這種Web Service事務管理機制的構想及原理,真正付諸實作的話,還是需要擴充、抽象一些Spring和Axis2的類型,同時還需要注意很多問題諸如線程安全、适用性等,另外,對于事務資料傳送對象(Transaction DTO)等的規範也需要詳細定義……
我已經在一個開源項目中對此事務管理架構有了實作,可以參考:
<a href="mailto:ClearWork@SourceForge">ClearWork@SourceForge</a>
ClearWork對Axis2的擴充 - 基于自定義政策的Web Service事務控制
在這個項目Web Service子產品中可以找到本文的實作代碼。
本文轉自胡奇 51CTO部落格,原文連結:http://blog.51cto.com/huqicto/280644,如需轉載請自行聯系原作者