配置SCA 元件參與WS-AT 全域性事務

CloudSpace發表於2008-07-21

事務 (transaction) 支援對於構建可靠的分散式應用至關重要。面向服務的元件體系結構 (SCA) 為我們提供了一個與實現無關的開發架構,SCA 元件是構建 SOA 應用的基本單位,本文將介紹 SCA 對事務的支援,以及如何使用 WebSphere Integration Developer (WID) 開發與配置支援全域性事務的 SCA 應用。

引言

本文將講述如何用 WID 開發執行於 WebSphere Process Server(WPS) 上的支援全域性事務的 SCA 應用。首先將介紹事務相關概念,接著講述 SCA 對事務的支援,最後我們通過一個示例演示如何在元件層次制定事務屬性,開發支援 WS-AT 全域性事務的 SCA 應用,。

概念介紹

  • 事務 :保證一組對於資源的更新活動以原子的方式執行。也就是說,要麼事務中所有的資源更新都被執行,其結果被永久儲存;要麼所有活動都不執行。
  • Resource Manager Local Transaction (RMLT):RMLT 是從資源管理器角度來看,通過單一連線使用資源的區域性事務。支援 RMLT 的資源管理器,包括通過資源介面卡 (Resource Adapter) 進行訪問的 EIS,通過 JDBC DataSource 訪問的關聯式資料庫,JMS 佇列,等等。
  • Global Transaction( 全域性事務 ):當一個應用使用到多個資源時,需要一個外部的事務管理器通過全域性事務來協調對各個資源的更新。在 J2EE 中,使用 BMT(Bean Managed Transaction) 的 EJB 元件,應用程式客戶端元件,web 元件等可以通過 Java Transaction API(JTA) 的 userTransaction 介面來建立 / 參與到全域性事務中;採用 CMT(Bean Managed Transaction) 的 EJB 元件則由容器負責劃分事務。
  • WS-AT: Web service atomic transaction (WS-AT) 是 IBM,Microsoft, BEA 等提出的在 web service 應用之間使用分散式全域性事務的協議,全域性事務的參與者通過兩階段提交協議來協調事務狀態,確保所有事務參與者能夠達到一致的狀態 , 即所有參與者都回滾或者提交。WS-AT 本身並沒有定義新的事務介面,全域性事務的劃分仍然通過標準的 JTA 介面來定義。當執行於全域性事務的 J2EE 應用程式發起 web service 請求時,事務管理器將在 SOAP header 中自動插入對應的 WS-AT CoordinationContext。web service 目標元件接受到請求時,其事務管理器將根據傳送過來的 WS-AT CoordinationContext 建立從屬於此全域性事務的 JTA 事務,從而 web service 的各個參與者都執行於同一個全域性事務上下文中。
  • WPS 對事務的支援 :WPS 從 version 6.0 開始實現了對 WS-AT 的支援。WPS 可以作為事務管理器來協調全域性事務,也可以作為全域性事務參與者參與到全域性事務中,同時也為 RMLT 提供執行環境。

SCA 中的事務的支援

Service Component Architect (SCA) 中,元件擁有標準的介面 (WSDL,java interface 等 ),元件的實現形式可以是 BPEL,POJO,business rule 等等。這些 SCA 元件可以匯出為外部應用程式所使用,也可以匯入外部元件為自身使用。SCA 元件對於事務的支援通過 QoS 來指定。開發者在 SCA 組裝的時候可以為其指定事務相關的 Qualifier,SCA runtime 將根據事務 QoS 屬性在執行時提供相應的事務支援。WID 為 SCA 元件提供了強大的開發工具。對於 SCA 元件的事務屬性定製,WID 同樣提供了方便的編輯工具。

具體來說,在開發和組裝 SCA 的時候可以在 Interface(介面)和 implementation(實現)兩個方面為元件指定事務支援屬性:

  • Component Implementation Qualifier for transaction:

元件實現的 Qualifier 屬性指定了元件在執行時對於安全性,事務等 QoS 的要求。其中 "Transaction' 屬性表明了元件執行時對活動的邏輯劃分,其取值與意義如下:

Global:若客戶請求傳播了全域性事務上下文,則元件執行於此全域性事務中;若不存在已有的全域性事務,則會新建一個全域性事務。

Local:元件執行於一個區域性事務中,該事務不能跨域容器邊界。

Any:若存在全域性事務上下文,則元件將執行於此全域性事務中;否則元件將執行於區域性事務中。

  • Component interface Qualifier for transaction:

元件介面的 Qualifier 是元件對外部的 QoS 宣告,是元件與其客戶端互動的協約。其中的 "Join Transaction" 屬性宣告瞭元件與客戶端參與事務的特性,其取值與意義如下:

True:元件執行時容器將參與到任何客戶端傳播過來的事物中。

False:元件執行時容器不參與到客戶端傳播的事務中。

介面和實現的事務屬性一起決定了元件執行時的事務特徵:

Interface - Join Transaction qualifier Implementation - Transaction Value qualifier 元件事務行為
True Global 元件將執行於傳播來的全域性事務中,否則將新建一個全域性事務
True Local 不相容,在 WID 中將導致檢查錯誤
True Any 元件將執行於傳播來的全域性事務中,否則將執行於本地事務中
False Global 元件將執行於新建的全域性事務中
False Local 元件將執行於本地事務中
False Any 元件將執行於本地事務中


在 SCA 應用中應用 WS-AT

本小節通過一個示例介紹如何為 SCA 元件定製全域性事務支援。

場景說明

示例模擬這樣一個簡單的銀行轉帳流程,包括取款 (withdraw balance) 和存款 (add balance) 兩個階段,這兩個階段的功能分別由兩個 SCA 元件實現,如【圖一】所示。AccountTransfer 元件由 BPEL 流程實現,組裝取款與存款元件以完成轉帳功能,如【圖二】所示。我們將通過配置 SCA 事務支援,以保證存款與取款兩元件的操作結果一致,即兩者都提交或者兩者都回滾。


圖一 Account Transfer 服務組裝圖


圖二 Account Transfer BPEL 流程圖

應用實現

  • 存款元件由 java 實現,當交易額大於 1000 時丟擲 Exception。其主要程式碼為:
public String add(String account, Integer amount) throws Exception {
		//TODO Needs to be implemented.
		if(amount.intValue()>1000){
			throw new Exception("tranfer amount"+amount.intValue()+" 
			 is too large at a time");
		}
		return "OK";
	}

  • 取款元件由 java 實現,並匯出為 web service,為 AccountTransfer 流程所呼叫。取款元件從資料庫中對應的帳號減去取款數額,其主要程式碼為:
public String withdraw(String account, Integer amount) throws 
 NamingException, SQLException {
		//TODO Needs to be implemented.
		Connection con = this.getConnection_DS();
		Statement st = con.createStatement();
		
String sql="update account set amount=amount-"+amount.intValue()+" 
 where accid='"+account+"'";
		st.executeUpdate(sql);
		
		st.close();
		con.close();
		
		return "SUCC";
	}
	
	private Connection getConnection() throws NamingException, SQLException {

		Connection con = null;
		DataSource ds = null;
	
		ds = (DataSource) new InitialContext().lookup("jdbc/account");
		
		con = ds.getConnection();
		
		return con;
	}

SCA 事務配置

本部分介紹如何對 SCA 進行全域性事務配置。我們的應用包括三個 SCA 元件:轉帳元件,由 BPEL 實現;取款元件和存款元件均由 Java 實現。我們將根據前面介紹的概念為元件配置事務 QoS 屬性。顯然,要讓三個元件參與到全域性事務中,元件實現的 Transaction 屬性應該設為”Global”, 元件介面的”Join Transaction”屬性應該設為”True”。

  1. 在 WID 中匯入專案交換檔案 accounttransfer.zip , 切換至 Business Integration 檢視,如【圖三】所示。

圖三 AccountTransfer 專案檢視

  1. 在 Assembly Diagram 中開啟 AccountTransferModule,選擇”addBalanceComp”元件,在”Properties”頁中依次選擇”Details”=>”Interfaces”=>”addBalance”=>”Qualifiers”, 為其新增”Join transaction” QoS 屬性,其值設為”true”,如【圖四】所示。

圖四配置存款元件介面事務屬性

選擇”Implementation”=>”Qualifiers”, 為其新增”Transaction” QoS 屬性 , 其值設為”Global”,如【圖五】所示。


圖五配置存款元件實現事務屬性

3. 按照與步驟 2)同樣的方式,為”withdrawBalanceWSImport”匯入新增”Join Transaction”QoS 屬性,其值設為”true”; 在 Assembly Diagram 中開啟 DelBalanceModule, 為”withdrawComp”元件在 Interface 上新增”Join transaction” QoS 屬性,其值設為”true”,在 implementation 上新增”Transaction” QoS 屬性 , 其值設為”Global”。

4. 對於實現為 BPEL 的元件,我們可以看到全域性事務屬性預設已經被選上

5. 儲存設定,重新 build 專案。

WS-AT 事務配置

本部分介紹如何在 WID 中為應用配置 WS-AT 全域性事務支援,關於 WS-AT 更詳細的介紹,請參考【文獻 1】。

在 WID 中切換至”J2EE”檢視,在”Project Explorer”中選擇“Dynamic Web Projects” => ”AccountTransferModuleWeb”, 雙擊”Deployment Descriptor”, 在”Servlets” Tab 中選中” AccountTransferServiceExport1_AccountTransferServiceHttpPort”,在”Global Transaction”欄中選上”Send Web Service Atomic Transaction on requests”, 如【圖六】所示。這表明 AccountTransfer 應用將在呼叫 Web Service 的請求中傳送 WS-At Context。


圖六為 AccountTransfer 應用配置 WS-AT

建立資料來源

1. 在 DB2 中建立資料庫 account。在 account 資料庫中按照如下 SQL 建立 account 表:

CREATE TABLE "ADMINISTRATOR"."ACCOUNT" (
		 "ACCID" VARCHAR(10) NOT NULL , 
		 "AMOUNT" INTEGER NOT NULL ); 
ALTER TABLE "ADMINISTRATOR"."ACCOUNT" 
	ADD CONSTRAINT "PK_ACCID" PRIMARY KEY
		("ACCID");

2. 向 account 表中新增測試用資料:

Insert into account values (‘acc001’,10000);
Insert into account values (‘acc002’,10000);

3. 在 WPS 管理控制檯上為 account 資料庫建立 jdbc 資料來源,其 JNDI 為”jdbc/account”, 在這裡我們使用”DB2 Universal JDBC Driver Provider(XA)”型別資料來源。

部署與測試

1. 將 AccountTransferModule 和 DelAccountModule 匯出為 EAR,部署到 WPS 上。

2. 在 WID 中用 Web Service Explorer 測試 AccountTransfer 服務如下:

測試一:從賬號 acc001 轉帳 500,服務返回成功。輸入與結果如【圖七】所示:


圖七測試成功 case

測試二:從帳號 acc002 轉帳 2000,服務返回異常,在資料庫中開啟 account 表,可以發現賬戶餘額沒有發生變化。這是因為交易額大於 1000,存款元件丟擲異常,處於 WS-AT 全域性事務的取款元件所作操作被回滾。服務返回訊息為:



soapenv:Server.generalException 

 
 



注意事項

  • 參與 WS-AT 全域性事務的資料來源必須支援兩階段提交協議,例如支援 XAResource 介面的資料來源。
  • 參與全域性事務的元件,其事務的提交由全域性事務管理器來決定,不能在元件中使用 Connection.commit 方法,這樣將導致執行時錯誤。
  • WS-AT 適用於 short duration 的流程。由於兩階段提交協議通過對資源加事務鎖來實現,不適合 long running 的流程,而通常採用 compensation 的方式
  • 對於應用了全域性安全的 WPS,您需要進行額外的配置以支援 WS-AT, 請參考【文獻 2】中對於 WS-AT 部分的說明

總結

本文介紹了 SCA 中的事務相關概念,通過本文的例子可以看到,SCA 提供了一個與實現無關的開發架構,不論其實現為 BPEL 還是 POJO,我們都可以方便的通過其事務 QoS 屬性,宣告式地配置元件的事務行為。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14789789/viewspace-406634/,如需轉載,請註明出處,否則將追究法律責任。

相關文章