Sun ONE logo      上一個      目錄      索引      下一個     

Sun ONE Application Server 7 管理員指南

第 9 章
使用作業事件服務

作業事件是企業不可或缺的一個組成部分。典型的企業作業事件包含雙方或多方之間的資產轉移。通常將這類轉移的精確記錄儲存於一個或多個資料庫中。由於這些資訊對於企業的運作至關重要,因此必須保持其有效性、現時性與可靠性。作業事件處理對於程式設計的初學者而言,可能有些困難。J2EE 平台提供數個抽象的概念來簡化可靠作業事件處理應用程式的開發程序。在本章中,我們將討論 Sun ONE Application Server 中的 J2EE 作業事件與作業事件支援。

本章對 Java 作業事件做一般的討論,而專門討論併入至 Sun ONE Application Server 的作業事件支援。

本章包含以下主題:


何為作業事件?

若要模仿企業的作業事件,一個程式可能需要執行數個步驟。例如,一個財務程式需要透過執行以下以虛擬碼列示的步驟,才能將資金從活期存款帳戶轉入儲蓄存款帳戶:

begin transaction

debit checking account

credit savings account

update history log

commit transaction

在上述的虛擬碼中,begincommit 敘述用於標記作業事件的界限。若要完成此作業事件,所有的三個步驟都必須成功地完成。如果未能成功地完成所有三個步驟,資料的完整性可能會受損。

這種保證被稱為不可分性。作業事件可以用兩種方式結束:透過 commit 結束或透過 rollback 結束。作業事件確定之後,敘述在作業事件界限內所做的修改會被永久地儲存起來。這些變更具有持久性,也就是說,即使今後發生系統故障,它們也會保持不變。如果作業事件中的任何敘述失敗,該作業事件會回轉,並復原到目前為止作業事件內由已執行敘述產生的所有影響。例如,在虛擬碼中,如果磁碟機在執行 credit 步驟期間當機,作業事件會回轉並復原由 debit 敘述所做的資料修改。

即使作業事件失敗,資料仍會保持完好無缺,因為作業事件帳戶仍處於平衡狀態。該作業事件行為被稱為作業事件的一致性

作業事件服務還提供隔離,表示在作業事件確定或回轉之前,其他的應用程式或執行緒不能觀察該作業事件的各個階段。一旦作業事件確定之後,其便能夠安全地被應用程式與執行緒觀察。


J2EE 中的作業事件

J2EE 中的作業事件處理包括以下五個參與者:作業事件管理員、應用程式伺服器、資源管理員、資源介面以及使用者應用程式。透過執行不同的 API 與功能,它們當中的每個項目都有助於作業事件處理順利地進行,如下所述:

術語資源管理員經常與資源介面相互替換使用,因為兩個實體之間有著緊密的聯繫。


作業事件資源管理員

J2EE 作業事件中支援以下作業事件資源管理員。

資料庫

資料庫是 J2EE 應用程式中最常遇到的作業事件資源管理員。JDBC 是 J2EE 元件用來存取資料庫的 API。資料庫資源被配置為 JDBC 資源。JDBC 資源由資源管理員或 JDBC 驅動程式進行管理。JDBC 驅動程式可以為本機作業事件或全域作業事件提供支援,在某些情況下,可同時支援本機作業事件與全域作業事件。

Sun ONE Application Server 支援經由各種 J2EE 元件使用 JDBC 與作業事件。如需有關如何註冊與配置 JDBC 資源的更多詳細資訊,請參閱關於 JDBC 資源。應用程式伺服器負責提供作業事件的連續性 (即,初始化作業事件,並經由多個應用程式元件存取資料庫)。例如,Servlet 可以啟動作業事件、存取資料庫、呼叫企業 Bean (作為同一作業事件的一部分存取同一資料庫),最後確定作業事件。

JMS 提供者程式

JMS 代表 Java Message Service。JMS 提供者是用於訊息代理程式服務的 J2EE 術語。JMS API 在應用程式之間提供可靠的作業事件訊息交換。對作業事件 JMS 資料來源的支援是 J2EE 中的一項必備功能。JMS 資源和 JDBC 資源可以參與同一項作業事件。

Sun ONE Application Server 與 Sun ONE Message Queue 整合使用,後者是一個功能齊全的 JMS 提供者,並且是相應的作業事件資源管理員。透過這種方式,Sun ONE Application Server 可以經由 Servlet、JSP 頁面以及企業 Bean 啟動作業事件 JMS 存取。也可以將協力廠商 JMS 提供者與 Sun ONE Application Server 結合使用。如需更多詳細資訊,請參閱第 11 章「使用 JMS 服務」

J2EE 連接器

Sun ONE Application Server 支援將 XATransaction 模式作為作業事件資源管理員使用的資源介面。平台必須經由 Servlet、JSP 頁面、以及企業 Bean 啟用對資源介面的作業事件存取。也可以經由單一作業事件內的多個應用程式元件存取資源介面。例如,Servlet 可能要啟動作業事件、存取資源介面、呼叫企業 Bean (也作為同一作業事件的一部分存取資源介面),最後確定作業事件。


本機作業事件與分散式作業事件

僅包含一種資源的作業事件可以使用本機作業事件完成。本機作業事件也需要所有參與的應用程式元件在一個程序中執行。包含多種資源,或多個參與程序的作業事件會變為分散式作業事件或全域作業事件。本機作業事件最佳化使用特定的資源管理員最佳化,可以使 J2EE 應用程式對其進行觀察。

作業事件類型在很大程度上由相關資源管理員執行的介面所決定。例如,執行 javax.sql.DataSource 介面的 JDBC 資料來源可以參與本機作業事件。執行 javax.sql.XADataSource 介面的資料來源能夠參與全域作業事件。某些 JDBC 資源執行兩種介面,當這樣的 JDBC 資源透過 Sun ONE Application Server 註冊時,可能需要在 Sun ONE Application Server 配置中提供附加配置資訊,以指出該資源優先使用的功能。

與全域作業事件相比,本機作業事件更為簡單,並且自然更為有效。當需要轉變的資料在多個資料來源中展開的時候,本機作業事件便無法勝任該項作業。有時,不可能預知作業事件內需要利用的資料來源數目。因此,我們在工作中經常會遇到全域作業事件。全域作業事件可以執行某些效能增強的最佳化作業。

J2EE 支援作業事件應用程式結合使用 Servlet 或 JSP,在一項作業事件中存取多個企業 Bean。每個元件可以使用一個或多個連線來存取一個或多個作業事件資源管理員。在下圖中,呼叫樹經由存取多個企業 Bean 的 Servlet 或 JSP page 啟動,這樣反過來可能會存取其他企業 Bean。元件通過連線存取資源管理員。

作業事件中的 J2EE 元件存取資源

該圖描述顯示作業事件中所有元件的呼叫樹。

例如,應用程式可能要求上圖中的所有元件作為單一作業事件的一部分存取資源。應用程式伺服器提供者必須提供作業事件功能來支援這樣的方案。

J2EE 作業事件管理支援相同層級的作業事件。相同層級的作業事件不能包含任何子作業事件 (嵌套式)。

作業事件恢復是分散式作業事件的一個重要方面。如果資源在關鍵時刻不可存取,或者發生其他不可恢復的錯誤,則分散式作業事件的狀況可能有問題。自動與手動恢復中斷的或不完全的作業事件是 Sun ONE Application Server 中的一項重要功能。您可以使用管理介面啟用自動作業事件恢復功能。如需有關如何控制作業事件恢復的更多資訊,請參閱作業事件服務管理

連線 (在此處作為資源的同義詞) 可被標示為可共用或不可共用。一個 J2EE 應用程式元件若採用非共用方式的連線,就必須為連線作業提供其部署資訊,以避免容器共用該連線。在已變更的安全屬性、隔離層、字元設定值,以及本土化配置的情形下需要該資訊。

容器不應該嘗試共用標示為不可共用的連線。如果未將連線標示為不可共用,則必須讓應用程式知曉實際上是否共用這些連線。

J2EE 應用程式元件可以使用選擇性的部署描述元元素 res-sharing-scope,指示是否可以共用與資源管理員的連線。如果尚未提供部署提示,容器應該假定連線是可共用的。J2EE 應用程式元件可以快取連線物件,並且可以在多個作業事件中重複使用這些連線物件。提供連線共用的容器應該透通地切換此類快取連線物件 (在派送時間),以在正確的作業事件範圍內指向適當的共用連線。

設計企業 Bean 應用程式時,開發人員必須確定指定界限的方式。


容器管理作業事件

在具有容器管理作業事件的企業 Bean 中,EJB 容器設定作業事件的界限。您可以使用任何企業 Bean 類型的容器管理作業事件:階段作業 Bean、實體 Bean 或訊息導引 Bean。容器管理作業事件簡化了開發程序,因為企業 Bean 程式碼不會明確地標示作業事件的界限。程式碼不包括開始與結束作業事件的敘述。

通常,容器會在企業 Bean 方法啟動前的瞬間開始一項作業事件。並在方法結束前的瞬間確定作業事件。每一種方法均可以與一項單一的作業事件關聯。在一種方法中不允許有嵌套式作業事件或多項作業事件。

容器管理作業事件不要求所有方法均與作業事件相關聯。部署 Bean 時,您可以經由設定作業事件的屬性來指定與作業事件相關聯的 Bean 方法。

本章節包含以下主題:

作業事件屬性

作業事件屬性控制作業事件的範圍。下圖展示控制範圍重要的原因。在圖中,方法 A 開始一項作業事件,然後呼叫 Bean 2 的方法 B,當方法 B 執行時,其會在由方法 A 啟動的作業事件範圍內執行,還是在一個新的作業事件範圍內執行?答案取決於方法 B 的作業事件屬性。

圖 9-1 作業事件屬性

圖中顯示作業事件的範圍。

作業事件屬性可以含有以下其中一個值:

Required

如果用戶端正在作業事件中執行,並呼叫企業 Bean 方法,則方法會在用戶端的作業事件中執行。如果用戶端與作業事件無關聯,容器會在執行方法之前啟動新的作業事件。

Required 屬性適用於大多數作業事件。因此,您可能想要將該屬性作為預設值使用,至少在開發的早期階段這樣做。由於作業事件屬性具有宣告性,因此,以後您可以輕鬆地對其進行變更。

RequiresNew

如果用戶端正在作業事件中執行,並呼叫企業 Bean 方法,則容器會採取以下步驟:

如果用戶端與作業事件無關聯,容器會在執行方法之前啟動新的作業事件。

如果要保證方法總在新的作業事件中執行,請使用 RequiresNew 屬性。

Mandatory

如果用戶端正在作業事件中執行,並呼叫企業 Bean 方法,則方法會在用戶端的作業事件中執行。如果用戶端與作業事件無關聯,容器會拋出 TransactionRequiredException

如果企業 Bean 方法必須使用用戶端的作業事件,則使用 Mandatory 屬性。

NotSupported

如果用戶端正在作業事件中執行,並呼叫企業 Bean 方法,則容器在呼叫方法之前會暫停用戶端的作業事件。方法完成之後,容器會繼續用戶端的作業事件。

如果用戶端與作業事件無關聯,容器在執行方法之前不會啟動新的作業事件。

對於不需要作業事件的方法,請使用 NotSupported 屬性。由於作業事件包含耗用時間,因此該屬性可能會提昇效能。

Supports

如果用戶端正在作業事件中執行,並呼叫企業 Bean 方法,則方法會在用戶端的作業事件中執行。如果用戶端與作業事件無關聯,容器在執行方法之前不會啟動新的作業事件。

由於方法的作業事件行為可能變化,因此您應該慎用 Supports 屬性。

Never

如果用戶端正在作業事件中執行,並呼叫企業 Bean 方法,則容器會拋出 RemoteException。如果用戶端與作業事件無關聯,容器在執行方法之前不會啟動新的作業事件。

屬性摘要

下表概括作業事件屬性的作用。T1 與 T2 作業事件均由容器控制。T1 作業事件與在企業 Bean 中呼叫方法的用戶端相關聯。在多數情況下,用戶端是另一個企業 Bean。T2 作業事件由容器在方法執行前的瞬間啟動。

在最後一欄中,術語「無」表示企業方法不在由容器控制的作業事件中執行。但是,這種企業方法中的資料庫呼叫可能由 DBMS 的作業事件管理員控制。.

表格 9-1 作業事件屬性

作業事件屬性

用戶端的作業事件

企業方法的作業事件

Required

T2

T1

T1

RequiresNew

T2

T1

T2

Mandatory

錯誤

T1

T1

NotSupported

T1

Supports

T1

T1

設定作業事件屬性

由於作業事件屬性儲存在部署描述元中,因此可以在 J2EE 應用程式開發的以下幾個階段中進行變更:企業 Bean 的建立階段、應用程式的組譯階段以及部署階段。但是,開發人員還應該在建立 Bean 時負責指定屬性。只有將各元件組譯到大型應用程式的應用程式開發人員才能修改屬性。部署 J2EE 應用程式的人員不負責指定作業事件屬性。

您可以為整個企業 Bean 或個別方法指定作業事件屬性。如果您為方法指定了一個屬性,而為 Bean 指定了另一個屬性,則方法屬性優先。為個別方法指定屬性時,Bean 的類型與需求不一致。階段作業 Bean 需要為企業方法定義的屬性,但是禁用 create 方法的屬性。實體 Bean 需要企業方法、create 方法、remove 方法以及 finder 方法的作業事件屬性。訊息導引 Bean 需要 onMessage 方法的作業事件屬性 (RequiredNotSupported)。

回轉容器管理作業事件

有兩種方法可以回轉容器管理作業事件。第一種,如果拋出一個系統異常,容器將會自動回轉作業事件。第二種,透過呼叫 EJBContext 介面中的 setRollbackOnly 方法,Bean 方法指導容器回轉作業事件。如果 Bean 拋出一個應用程式異常,則回轉不能自動進行,但可以呼叫 setRollbackOnly 來引發回轉。

在以下範例中,BankEJB 範例的 transferToSaving 方法展示 setRollbackOnly 方法。如果發生活期存款帳戶結欠,transferToSaving 會呼叫 setRollBackOnly 並拋出一個應用程式異常 (InsufficientBalanceException)。updateCheckingupdateSaving 方法會更新資料庫表格。如果更新失敗,這些方法會拋出一個 SQLException,而 transferToSaving 方法會拋出一個 EJBException。由於 EJBException 是系統異常,因此,其會導致容器自動回轉作業事件。以下為 transferToSaving 方法的程式碼:

public void transferToSaving(double amount) throws
  InsufficientBalanceException {

  checkingBalance -= amount;
  savingBalance += amount;

if (checkingBalance < 0.00) {
context.setRollbackOnly();

throw new InsufficientBalanceException();
}
  try {
    updateChecking(checkingBalance);

  updateSaving(savingBalance);
}  catch (SQLException ex) {
    throw new EJBException
   ("Transaction failed due to SQLException: "
   + ex.getMessage());
}
}

當容器回轉作業事件的時候,總會復原 SQL 呼叫在作業事件內對資料所做的變更。但是,只有在實體 Bean 中,容器才會復原對實例變數所做的變更。(透過自動呼叫實體 Bean ejbLoad 方法 [經由資料庫載入實例變數],可以執行該項作業。)發生回轉的時候,階段作業 Bean 必須明確地重設在作業事件內變更的所有實例變數。若要重設階段作業 Bean 的實例變數,最簡單的方法是執行 SessionSynchronization 介面。

您也可以透過指令行介面傳送作業事件 ID,來回轉作業事件。如需更多詳細資訊,請參閱使用指令行介面管理作業事件

同步化階段作業 Bean 的實例變數

SessionSynchronization 介面 (選擇性) 可讓您同步化實例變數及其在資料庫中相應的值。容器在作業事件的每個主要階段都會呼叫 SessionSynchronization 方法 - afterBeginbeforeCompletion 以及 afterCompletion

afterBegin 方法會在新的作業事件開始後通知實例。容器首先呼叫 afterBegin,然後才呼叫作業事件中的第一個企業方法。afterBegin 方法是經由資料庫載入實例變數的絕佳位置。例如,BankBean 類別使用 afterBegin 方法載入 checkingBalancesavingBalance 變數:

public void afterBegin() {

 System.out.println("afterBegin()");
 try {
  checkingBalance = selectChecking();
  savingBalance = selectSaving();
 } catch (SQLException ex) {
  throw new EJBException("afterBegin Exception: " +
      ex.getMessage());
}
}

在企業方法完成之後、而作業事件確定之前的瞬間,容器呼叫 beforeCompletion 方法。beforeCompletion 方法是階段作業 Bean 回轉作業事件的最後機會 (透過呼叫 setRollbackOnly)。如果還沒有透過實例變數的值更新資料庫,則階段作業 Bean 會使用 beforeCompletion 方法執行這項作業。

afterCompletion 方法表示作業事件已經完成。它只有一個單一的布林參數,如果作業事件被確定,其值為 true,如果作業事件被回轉,則其值為 false。如果發生回轉,階段作業 Bean 便可以使用 afterCompletion 方法,重新顯示其資料庫中的實例變數:

public void afterCompletion(boolean committed) {

 System.out.println("afterCompletion: " + committed);
 if (committed == false) {
  try {
   checkingBalance = selectChecking();
    savingBalance = selectSaving();
} catch (SQLException ex) {
    throw new EJBException("afterCompletion SQLException:
" + ex.getMessage());
}
}
}

容器管理作業事件中禁用的方法

您不應該呼叫任何可能干擾作業事件界限 (由容器設定) 的方法。禁用的方法列示如下:

但是,您可以使用這些方法在 Bean 管理式的作業事件中設定界限。


Bean 管理式的作業事件

在 Bean 管理式的作業事件中,階段作業或訊息導引 Bean 中的程式碼明確地標示了作業事件的界限。實體 Bean 不能具有 Bean 管理式的作業事件,其必須使用容器管理作業事件作為替代。儘管具有容器管理作業事件的 Bean 需要較少的編碼,但是它們有一個限制條件:方法在執行時可以與單一的作業事件關聯,也可以根本不與任何作業事件關聯。如果該限制條件令您在編碼 Bean 時感到困難,應該考慮使用 Bean 管理式的作業事件。

以下虛擬碼展示您可以透過 Bean 管理式的作業事件取得的細紋控制。透過檢查各種情況,虛擬碼決定是否啟動或停止企業方法內的作業事件。

begin transaction
...
update table-a
...
if (condition-x)
 commit transaction
else if (condition-y)
 update table-b
 commit transaction
else
 rollback transaction
 begin transaction
 update table-c
 commit transaction


作業事件服務管理

您可以使用管理介面或指令行介面管理作業事件。

本章節包含以下主題:

使用管理介面管理作業事件

使用管理介面,您可以啟用對作業事件的監視、設定其日誌層級以及指定其進階選項。

您可以控制實例的作業事件服務屬性,例如恢復策略和逾時。您在此處指定的特性與配置儲存在 server.xml 檔案中。

若要配置作業事件服務選項,請執行以下工作:

  1. 在管理介面的左窗格中,開啟您要修改其作業事件配置的 Sun ONE Application Server 實例樹。
  2. 從顯示的 J2EE 服務清單中選取 [Transaction Service]。在管理介面右窗格的視圖配置作業事件服務選項中,您將看到以下視窗:

圖 9-2 配置作業事件服務選項

該圖顯示 Java 作業事件服務的可配置進階服務選項。

  1. 若要啟用對作業事件的監視,請標示 [Monitoring Enabled] 核取方塊。下表列示 Java 作業事件服務中可被監視的功能:
  2. 表格 9-2 Java 作業事件服務的可監視屬性

    特性

    類型

    描述

    transactionsCompleted

    int

    啟用監視後所完成的作業事件數目

    transactionsRolledBack

    int

    啟用監視後已回轉的作業事件數目

    transactionsRecovered

    int

    啟用監視後已恢復的作業事件數目

    transactionsInFlight

    int

    正在處理的作業事件數目

    timeStamp

    long

    以毫秒表示,記錄產生統計資料的時間。這將是由 System.getCurrentTimeInMillis() 報告的任何內容

  3. 從 [Log Level] 下拉式清單中,選取您要為作業事件設定的日誌層級。如需有關日誌層級及其併入方式的更多資訊,請參閱第 5 章「使用記錄功能」
  4. 標示 [Recover on Restart] 核取方塊,以在伺服器重新啟動時自動恢復失敗的作業事件。當資源在作業事件確定協定的關鍵時刻不可存取時,作業事件也許不會完成,並繼續駐留在作業事件日誌檔中。如果已經標示了該核取方塊,伺服器會在重新啟動時嘗試恢復中斷的作業事件。如果有關資源仍然不可存取,也許會延遲伺服器的重新啟動。依預設,不標示該核取方塊。
  5. 對於具有容器管理作業事件的企業 Bean,您可以透過設定作業事件逾時 (秒) 特性的值來控制作業事件逾時間隔時間。
  6. 如果將該特性的值設定為 0,則作業事件便不會逾時。

    在 [Transaction Timeout] (以秒表示) 欄位中,指定作業事件逾時間隔時間。如果作業事件沒有在指定的時間內完成,其便會被回轉。如果該屬性的值設定為 0,則作業事件便不會逾時。

  7. 在 [Transaction Log Location] 欄位中,指定要儲存日誌檔的絕對目錄路徑。您需要重新啟動伺服器,以使新的作業事件日誌目錄生效。
  8. 從 [Heuristic Decision] 下拉式方塊中,選取您要套用至作業事件的啟發式決策。從指示的選項中選取 [Commit] 或 [Rollback],以便在不能明確地確定作業事件結果時,指定應用程式伺服器在恢復期間應該如何確定一個不確定作業事件的結果。如果將 [Heuristic Decision] 設定為 [Rollback],其便會將作業事件回轉。在某些情況下,也可以確定這樣的作業事件。
  9. 在 [Keypoint Interval (transactions)] 欄位中,指定日誌中要點事件作業之間作業事件的數目。透過移除已完成作業事件的項目,並壓縮檔案,要點事件作業可以縮小作業事件日誌檔的大小。如果該屬性值較大,則作業事件日誌檔也會較大,但是減少要點事件作業意味著更高的潛在效能。如果屬性值較小 (例如,100),則日誌檔也會較小,但是由於要點事件作業的頻率較大,會稍微降低效能。

使用指令行介面管理作業事件

您可以使用指令行介面 (CLI) 管理並監視資料庫作業事件,將在以下章節中加以解釋:

這些章節解釋如何使用指令行介面管理並監視作業事件。

列示執行中的作業事件

以下指令應該用於取得執行中的作業事件資料 (假定您處於多重模式下,並且已設定使用者名稱與密碼):

- asadmin> get --monitor <instanceName>.transaction-service.inflight-tx

多行輸出的形式為:-

Transaction Id State Elapsed Time (ms)

txnid1 Prepared 20

txnid2 Active 100

txnid3 Active 120

... ... ...

管理作業事件

列示執行中的作業事件中給定的範例內,讓我們假定您要透過以下作業事件 Id 來回轉作業事件:txn-idstxnid2 以及 txnid3。回轉所選作業事件的指令範例如下:

asadmin> set --monitor <instanceName>.transaction-service.rollback-list=txnid2,txnid3

凍結作業事件服務

若要凍結作業事件服務,請執行以下指令:

asadmin> set --monitor <instanceName>.transaction-service.freeze=true

凍結作業事件服務期間,應用程式伺服器中的作業事件管理員會暫停執行中的所有作業事件。在生產部署系統中,不建議使用凍結指令。

若要取消凍結作業事件服務,請執行以下指令:

asadmin> set --monitor <instanceName>.transaction-service.freeze=false

當作業事件服務重新設定為進行動作時,系統將在停止處開始繼續作業。如果活性系統保持的凍結狀態時間太長,某些資料庫連線可能逾時,導致作業事件被回轉。

監視作業事件

若要取得作業事件的監視資料 (包括執行中作業事件的資料),請執行以下指令:

asadmin> get --monitor <instanceName>.transaction-service.*

當您執行該指令時,如果沒有作用中的作業事件,將會得到以下輸出結果:

total-tx-completed = 5

total-tx-rolledback = 2

total-tx-inflight = 0

isFrozen = false

tx-inflight = No active transactions found.

當您執行該指令時,如果存在作用中的作業事件,將會得到以下輸出結果:

total-tx-completed = 5

total-tx-rolledback = 2

total-tx-inflight = 2

isFrozen = false

tx-inflight =

Transaction Id State Elapsed Time (ms)

txnid1 Prepared 500

txnid2 Active 360



上一個      目錄      索引      下一個     


Copyright 2003 Sun Microsystems, Inc. 。版權所有。