1. 程式人生 > >在 WebSphere Studio 中配置並使用 XA 分散式事務

在 WebSphere Studio 中配置並使用 XA 分散式事務

2004 年 9 月 01 日

本文描述了分散式事務,並向您演示瞭如何使用用於 DB2、Oracle 和 JMS 等可以在分散式事務中同時使用的 XA 資源來配置 WebSphere Studio Application Developer 測試伺服器。本文描述了一個在同一事務中更新資料庫併發送 JMS 訊息的會話 bean。由於必須配置 Oracle 資料庫以支援 XA 事務,因此本文展示了當 Oracle 資料庫沒有正確配置時會發生的 Java 異常,以及如何解決這些問題。

在開始研究如何使用分散式事務開發應用程式之前,讓我們回顧一下什麼是分散式事務以及為什麼說它們很有用。有幾個術語經常被混淆:事務、分散式事務、兩階段提交(two-phase commit)、XA 事務、事務傳播和 CORBA OTS 事務。但實際上這些術語的含義各不相同:

事務-- 作為工作的單一邏輯單元而執行的一系列操作,在執行過程中要麼所有的操作都被執行,要麼一個都不執行(也被稱為 本地或 簡單事務)。事務經常被描述為 ACID-- 原子性、一致性、隔離性和永續性。為使事務持久,在事務的試驗期所做的變更,最終必須用 提交操作作為事務的結尾。如果有任何變更不能被提交,則事務將 回滾(roll back),並取消所有的變更,恢復到事務從沒有發生之前的狀態。如果程式碼執行的操作決定不進行提交或者不能成功提交,那麼它必須回滾該事務以取消這些操作。如果在事務進行期間應用程式崩潰,則在重啟時,事務恢復將回滾該事務。在 寫事務中,所有的變更必須全部提交或者全部回滾。在 讀事務

中,沒有變更需要提交,但是事務會防止對正在被讀取的資料的修改,直到所有的讀操作全部結束。

分散式事務-- 兩個或更多事務資源(比如,兩個單獨的資料庫)之間的 ACID 事務。為使事務成功提交,所有的獨立資源必須全部成功提交。如果其中的任何一個沒有成功提交,則事務必須在所有的資源中回滾。

兩階段提交-- 一種分兩步提交分散式事務的方法: 第 1 階段,準備:每個資源報告是否其已經準備完畢,可以提交 -- 通常通過繼續並保持新資料,但仍然不刪除舊資料。 第 2 階段,提交:如果所有的資源都準備就緒,則全部進行提交 -- 在舊資料刪除且事務不再回滾之後進行。兩階段提交確保了分散式事務也可以始終提交或者始終回滾,即使在事務提交過程中系統的一部分崩潰,也不會受到影響。有許多(但不是全部)分散式事務的實現使用兩階段提交。

XA 規範-- 開放組織(Open Group)的 X/Open 分散式事務流程(DTP)模型,它定義了 應用程式如何使用 事務管理程式跨多個 資源管理程式來協調分散式事務。如果事務是通過遵循 XA 的事務管理程式來進行協調的,則任何遵循 XA 規範的資源管理程式都可以參與該事務,因此就可以讓不同廠商的事務產品可以共同工作。所有遵循 XA 的事務都是分散式事務。XA 既支援一步提交,也支援兩階段提交。

下圖是 XA 規範,它展示了分散式事務的各部分:


X/Open 分散式事務(DTP)模型
DTP 模型

事務傳播-- 通過將事務上下文作為執行緒的一部分進行傳遞,以允許多個合作物件參與單個事務。當執行緒經過合作物件時,事務管理程式使用執行緒的事務上下文來執行所有的工作。

CORBA OTS 規範-- 物件管理組(Object Management Group)的通用物件請求代理體系結構物件事務服務(Common Object Request Broker Architecture Object Transaction Service) -- 定義遵循規範的流程如何跨多個流程執行緒將事務上下文從一個流程傳播到另一個流程。這種傳播使得即使分散式物件運行於來自不同廠商的容器中,也可以在單個事務中合作。CORBA OTS 規範建立在 XA 規範的基礎之上。

下圖是 OTS 規範,它展示了包含分散式物件的事務的各部分:


物件事務服務(OTS)模型
OTS 模型

IBM® WebSphere® Application Server V5 為其應用程式提供既符合 XA 規範又符合 CORBA OTS 規範的事務管理程式。該事務管理程式實現了兩個 API,這兩個 API 是 Java™ 2 Enterprise Edition (J2EE) 的一部分 -- Java 事務 API(JTA),它提供對 Java 事務服務(Java Transaction Service,JTS)的簡單訪問。對於任何遵循 XA 規範的資源,JTA 的 XA 部分都有能力協呼叫這些資源的事務(通過介面 javax.transaction.xa.XAResource )。J2EE 中支援 XA 的兩個資源型別是 Java 資料庫連線(Java Database Connectivity,JDBC)API(通過介面 javax.sql.XAConnection)和 Java 訊息服務(Java Message Service,JMS)API(通過介面 javax.jms.XAConnection )。當一個容器中的 EJB 呼叫另一個容器中的 EJB 時,事務管理程式將使用 CORBA OTS。

當應用程式需要訪問或更新事務資源中的資料時,它應該(通常是必須)使用事務來進行該項工作。在沒有自動提交的標準 JDBC 程式碼中,應用程式使用一個連線來訪問和更新資料,然後提交該連線以結束這個事務(並啟動另一個事務)。當 JMS 客戶端傳送或接收訊息時,訊息傳遞提供方使用事務來向目標中新增訊息或從目標中刪除訊息。JMS 客戶端可以任意的顯式控制該事務,比如在同一個訊息傳遞系統中,協同處理從一個佇列接收訊息和向另一個佇列傳送訊息。

當應用程式有一個單獨的功能需要訪問或更新多個事務資源中的資料時,應該使用分散式事務。您可以在每個資源中使用獨立的簡單事務,但是這種方法很容易出錯。如果一個資源中的事務成功提交,而另一個資源中的事務提交失敗且必須回滾,那麼第一個事務將不再回滾,這將使應用程式的狀態不一致。如果一個資源成功提交,但在另一個資源成功提交前系統崩潰,那麼也會造成應用程式狀態不一致。

哪些功能需要訪問多個事務資源?以下是一些例子:

  • 在資料庫之間移動資料-- 將資料從一個數據庫移動到另一個數據庫的應用程式需要使用分散式事務。否則,資料可能會重複(如果插入成功但刪除失敗)或丟失(如果刪除成功但插入失敗)。
  • 在資料庫和訊息之間移動資料-- 應用程式需要將資料從 JMS 訊息移動到資料庫表,或者相反。如果不使用分散式事務,資料可能會重複或丟失。
  • 將訊息紀錄到資料庫-- 應用程式也許要使用資料庫來儲存“跟蹤紀錄”,“跟蹤紀錄”中記錄了該應用程式與合作伙伴應用程式進行交換的訊息。為了讓紀錄保持持久且準確,需要在傳送或接收訊息的分散式事務中記錄這些訊息。
  • 在訊息傳遞系統之間移動訊息-- 許多訊息傳遞場景包括接收一個訊息併發送另一個訊息作為結果。當兩個目的地在同一個訊息傳遞系統中時,接收和傳送可以在一個簡單事務中進行,這是因為它們只涉及單一的事務資源。然而,當從一個訊息傳遞系統接收訊息,並將訊息傳送到另一個單獨的訊息傳遞系統時,應用程式應該在兩個訊息傳遞系統間的分散式事務中執行操作,以確保訊息不會重複或丟失。
  • 與企業資訊系統(EIS)協同工作-- J2EE 規範包含 J2EE 聯結器體系結構,該體系結構用於實現介面卡以訪問企業資訊系統(EIS),比如 CICS 或 SAP。介面卡提供的事務支援級別 -- 無、本地或 XA -- 這取決於 EIS 被賦予的適配能力。如果介面卡支援 XA 事務,應用程式就可以使用分散式事務來協調 EIS 資源與 JDBC 和 JMS 資源。

基本上,只要應用程式使用多個事務性持久資源,就需要使用分散式事務。操作多個資源的任何功能都應該使用分散式事務。

Enterprise JavaBeans (EJBs) 有許多優點:元件化、遠端呼叫、安全性、永續性功能、訊息傳遞功能等等。儘管這些功能都很有用,但使用 EJB 的最大好處可能就是事務管理。EJB 和 容器管理事務(container-managed transactions,CMTs)使事務管理對於 bean 開發人員來說實質上是透明的。

EJB 上的每個公共方法都定義了 EJB 容器和 EJB 客戶端之間的事務邊界,並在部署描述符指定該邊界。這種方式的結果是客戶端呼叫的所有 EJB 程式碼都運行於單個容器管理事務中(直到部署描述符指定另一個),這樣程式碼的工作要麼全部執行,要麼全部回滾。此外,bean 開發人員實際上不需要編寫任何用於處理事務的程式碼,比如確定何時呼叫 commit() 方法以及呼叫失敗時該如何處理。容器通過事務邊界和部署描述符表示了事務模型,並在執行時控制事務的提交和回滾。

即使多個 EJB 合作執行任務時,EJB 容器管理事務也可以工作。一旦執行緒中的第一個 EJB 建立了事務上下文,事務容器將使用事務傳播來將該上下文傳遞到合作 EJB,這樣所有的工作都在同一事務中執行(直到部署描述符指定另一個)。即使合作 EJB 存在於不同的容器中,CORBA OTS 也可以啟用容器的事務管理程式進行協調,從而使事務跨容器傳播。

EJB 容器管理事務對控制分散式事務特別有幫助。該方法允許程式碼操作多套資料,而不需要關心資料是來自單個資源(需要簡單事務)還是多個資源(需要分散式事務)。應用程式只根據需要來使用 EJB 操作資料。EJB 容器的事務管理程式在執行時確定資料是來自單個資源(這種情況下它使用資源管理程式管理事務),還是來自多個資源(這種情況下使用事務管理程式管理事務,並協同資源管理程式)。不管資料來自於單個還是多個資源,EJB 程式碼保持不變,而由 EJB 容器適當的處理事務。





現在我們已經審查了想達到什麼目標。我們確定了分散式事務是什麼、有幫助且必需的場景,以及 EJB 技術如何使這些場景對 bean 開發人員大大簡化。現在我們使用 WebSphere Studio Application Developer(以下簡稱 Application Developer)來建立並執行一個簡單的範例。

這些程式碼片斷向您展示瞭如何建立 Application Developer 測試伺服器,以及如何為 JDBC 和 JMS 配置該伺服器。它向您演示了使用特定於本範例的值來填寫特定設定。每個表單前的描述說明了哪些值是適用於所有應用程式的,哪些值是特定於本範例的。

本範例也將說明如何為兩個常用 JDBC 資料庫產品(DB2® 和 Oracle)配置 XA 資料來源。還將說明如何用 XA 連線來配置 JMS 目的地。

為開始本範例,我們需要建立一個新的測試伺服器。為此,切換到 Servers 透檢視。從 Server Configuration 檢視的上下文(通過單擊滑鼠右鍵)選單,選擇 New =>Server and Server Configuration。在建立對話方塊中,輸入伺服器名稱(例如“XA Example Server”),選擇 Test Environment(對於本範例,WebSphere 5.0 版本或 WebSphere 5.1 版本都可以)作為伺服器型別,然後單擊 finish。


建立新伺服器和伺服器配置對話方塊
建立伺服器對話方塊

在建立資料來源之前,我們將建立 JAAS 身份驗證條目,以後我們將使該條目關聯到資料來源,以便登入資料庫。在伺服器配置編輯器中,切換到 Security 頁面。在 JAAS Authentication Entries 列表中新增一個條目。您的條目必須對您的資料庫有效,如本文所示,它能夠建立表和新增資料。在本範例中,我們將使用一個註冊範例,它是預設 Oracle 安裝的一部分。您可以通過特定的安裝來使用不同的註冊。

Oracle JAAS 身份驗證條目設定

屬性名稱 屬性值 是否預設?
Alias Scott
User ID scott
Password tiger

新增 JAAS 身份驗證條目對話方塊
新增 JAAS 對話方塊

對於本範例,伺服器配置必須包含 JNDI 中註冊的 JDBC 資料來源,比如 jdbc/OracleXADS 。它是 JDBC 提供者,並將作為 Oracle XA 資料庫而被訪問。

首先,我們需要建立描述如何訪問 Oracle XA 的 JDBC 提供者。在伺服器配置編輯器中,切換到 Data Source 頁面。在 JDBC 提供者列表中按下面所示新增一個提供者。名稱可以任選,我們將使用與提供者型別相同的名稱。

Oracle JDBC 提供者設定

屬性名稱 屬性值 是否預設?
JDBC Provider type Oracle JDBC Driver (XA)
Name Oracle JDBC Driver (XA)
Implementation class name oracle.jdbc.xa.client.OracleXADataSource default
Class path ${ORACLE_JDBC_DRIVER_PATH}/ojdbc14.jar default

建立 JDBC 提供者對話方塊
建立提供者對話方塊

第二步,建立 JDBC 資料來源以提供對特定 Oracle XA 資料庫的訪問。選擇我們剛剛建立的 Oracle 提供者,然後用如以下所示的設定新增一個數據源。名稱可以任選。JNDI 名是您的程式碼用來查詢資料來源的唯一識別符號。本文的範例程式碼使用 jdbc/OracleXADS 作為 JNDI 名。對於容器管理的身份驗證別名,選擇我們 先前建立的 JAAS 身份驗證條目。 URL 是所需的資源屬性,它指定訪問資料庫的路徑。

Oracle JDBC 資料來源設定

屬性名稱 屬性值 是否預設?
JDBC Provider type Oracle JDBC Driver (XA), version 5.0
Name Example Oracle XA Data Source
JNDI name jdbc/OracleXADS
Helper class com.ibm.websphere.rsadapter.OracleDataStoreHelper default
Authentication alias Scott
URL jdbc:oracle:thin:@localhost:1521:example

建立 JDBC 資料來源對話方塊
建立資料來源對話方塊

我們剛才建立的 JDBC 提供者會在特定的目錄中查詢它的 JAR 檔案,該目錄通過變數 ORACLE_JDBC_DRIVER_PATH 指定。該變數必須設定為正確的目錄,但 WebSphere Studio 並不知道您的 Oracle 客戶端安裝在哪裡,因此您必須指定該目錄。在伺服器配置編輯器中,切換到 Substitution variables 頁面。在 Node 設定下面是已定義變數列表。找到用於 Oracle 的變數,並將其設定為包含 ojdbc14.jar 檔案的目錄。

Oracle 定義的變數(對節點)設定

屬性名稱 屬性值 是否預設?
ORACLE_JDBC_DRIVER_PATH C:/oracle/ora92/jdbc/lib

編輯 Oracle JDBC 驅動程式路徑變數對話方塊
編輯變數對話方塊

現在您已經用 Oracle XA JDBC 資料來源配置了伺服器。儲存伺服器配置。

儘管您已經用 Oracle XA JDBC 資料來源配置了您的測試伺服器,但還需要對 Oracle 資料庫自身進行配置以使其支援 XA 事務。Oracle DBA 可以幫助您確定是否需要進一步的配置,並可以幫助您執行這些步驟。在本文的後面,我們將討論如果您的 Oracle 針對 XA 進行配置,將會出現什麼錯誤,以及如何進行正確的配置。

本範例還包含了 DB2 XA 資料來源。DB2 資料來源的配置設定與 Oracle 資料來源的配置設定很相似。

首先,定義一個 JAAS 標識用於登入到您的資料庫。在本範例中,我們設定了一個名為 DB2 的標識。

DB2 JAAS 身份驗證條目設定

屬性名稱 屬性值 是否預設?
Alias DB2
User ID db2
Password a_password

第二步,我們需要為 DB2 XA 資料來源建立一個 JDBC 提供者。

DB2 JDBC 提供者設定

屬性名稱 屬性值 是否預設?
JDBC Provider type DB2 Universal JDBC Driver Provider (XA)

Name

DB2 Universal JDBC Driver Provider (XA)
Implementation class name com.ibm.db2.jcc.DB2XADataSource default
Class path

${DB2UNIVERSAL_JDBC_DRIVER_PATH}}/db2jcc.jar

${UNIVERSAL_JDBC_DRIVER_PATH}}/db2jcc_license_cu.jar

${DB2UNIVERSAL_JDBC_DRIVER_PATH}}/db2jcc_license_cisuz.jar

default

第三步,需要使用 JNDI 名稱 jdbc/DB2XADS 建立 DB2 XA 資料來源。我們將使用在 第 1 步中建立的 JAAS 標識。儘管 Oracle 資料來源需要 URL 字串來訪問資料庫,但 DB2 資料來源只需要資料庫名稱,在本範例中資料庫名稱為“sample”。

DB2 JDBC 資料來源設定

屬性名稱 屬性值 是否預設?
JDBC Provider type DB2 Universal JDBC Driver Provider (XA), version 5.0
Name Example DB2 XA Data Source
JNDI name jdbc/DB2XADS
Helper class com.ibm.websphere.rsadapter.DB2UniversalDataStoreHelper default
Authentication alias DB2
databaseName sample

第四步,需要指定安裝 DB2 驅動程式的路徑,這是包含了 db2jcc.jar 檔案的目錄。另外,還需要核對資料來源類路徑中其他變數的預設值。

DB2 定義的變數(對節點)設定

屬性名稱 屬性值 是否預設?
DB2UNIVERSAL_JDBC_DRIVER_PATH C:/db2/SQLLIB/java
UNIVERSAL_JDBC_DRIVER_PATH ${WAS_INSTALL_ROOT}/universalDriver/lib default

現在您已經配置了 DB2 XA 資料來源,並將其註冊為 jdbc/DB2XADS 。儲存伺服器配置。

為了演示 XA 事務,我們還需要嵌入 JMS 資源。Application Developer 中內嵌了 JMS 模擬器,它是一個簡單的 JMS 資源,但卻包含了全部的 XA 功能。您的使用 DB2 或 Oracle XA 的 WebSphere 應用程式可以使用 JMS 以外的資源,但本範例需要使用 JMS。

在伺服器配置編輯器中,切換到 JMS 頁面。在 JMS Server Properties 下,新增佇列名 XAExampleQ 。在 JMS Provider 下,選擇 MQ Simulator for Java Developers。

在本範例中,伺服器配置必須包括兩個 JMS 資源:一個名為 jms/XAExampleQCF 的佇列連線工廠(queue connection factory)和一個名為 jms/XAExampleQ 的佇列。在伺服器配置編輯器的 JMS 頁面上,在 WASQueueConnectionFactories 條目列表中,按以下所示新增一個新的佇列連線工廠。確保 XA 支援被啟用,這是本範例中最重要的一點。

WAS 佇列連線工廠設定

屬性名稱 屬性值 是否預設?
Name XAExampleQCF
JNDI Name jms/XAExampleQCF
Enable XA Support True (checked) default

新增 WAS 佇列連線工廠對話方塊
新增 QCF 對話方塊

在 WASQueue 條目列表中,用以下設定新增一個新佇列:

WAS 佇列設定

屬性名稱 屬性值 是否預設?
Name XAExampleQ
JNDI Name jms/XAExampleQ

新增 WAS 佇列對話方塊
新增佇列對話方塊

儲存伺服器配置。

現在伺服器配置已經全部完成。它有一個用於通過 XA 訪問 Oracle 的資料來源,以及一個使用支援 XA 事務的佇列連線工廠的 JMS 佇列。您甚至現在就可以執行伺服器。它不包含任何應用程式,但您可以檢驗它是否可以正常啟動,並可以檢驗我們為該伺服器配置的 JNDC 中的對 JDBC 和 JMS 資源的繫結。成功的啟動將包含以下特定於 JMS 以及特定於 JDBC 的訊息:

JMSMQJDProvid A MSGS0656I: Starting the MQJD JMS Provider
JMSMQJDProvid A MSGS0650I: MQJD JMS Provider open for business
ResourceMgrIm I WSVR0049I: 
        Binding XAExampleQCF as jms/XAExampleQCF
ResourceMgrIm I WSVR0049I: 
        Binding XAExampleQ as jms/XAExampleQ
ResourceMgrIm I WSVR0049I: 
        Binding Example Oracle XA Data Source as jdbc/OracleXADS
ResourceMgrIm I WSVR0049I: 
        Binding Example DB2 XA Data Source as jdbc/DB2XADS
CacheServiceI I DYNA0048I: WebSphere Dynamic Cache initialized successfully.
      

您確實應該按以上描述的方法練習設定伺服器配置。但如果您配置不成功,並且希望執行下面將描述的範例應用程式,您可以匯入配置。

為了開始匯入,請下載並解壓縮範例檔案。它包含一個名為 XA Example Server.wsc 的目錄,這是 WebSphere version 5.1 伺服器配置。

在匯入伺服器配置之前,您首先需要建立一個伺服器,這在本文的開始部分就已經描述過。由於該配置適用於 5.1 版本,因此確保該伺服器是 WebSphere version 5.1 測試環境(在 Application Developer version 5.1.1 中有效)。

它還可以幫助您看到伺服器列表和配置列表。在 Server 透檢視的 Server Configuration 檢視中,點選 Menu 按鈕選擇 View =>Advanced


高階伺服器配置檢視選單
高階檢視選單

下一步,通過下列步驟匯入伺服器配置:

  1. 從 Studio 選單欄中,選擇 File =>Import
  2. 在 Select 頁面中開啟 Import 嚮導。選擇 Server Configuration並單擊 Next
  3. 嚮導切換到它的 Import a Server Configuration 頁面。
    1. 在 Configuration Name 欄位中,輸入一個名稱,該名稱必須不同於您剛才建立的伺服器名稱,比如“Imported Configuration”。
    2. Folder 欄位將是您的伺服器專案的預設名稱,通常名為“Servers”。
    3. 為 Configuration Type 選擇 WebSphere version 5.1 =>Server Configuration
    4. 在 Location 欄位中,單擊 Browse 並選擇您已經下載的 XA Example Server.wsc 檔案。
  4. 單擊 Finish以匯入伺服器配置。Server Configuration 檢視將列出您指定的新配置名稱。