レベル: 中級 田中 孝清, ソフトウェア事業 WebSphere テクニカルセールス,
IBM
2008年 2月 29日 WebSphere Application Server(以下WAS)のV6.0.2.19またはV6.1.0.9以降では,WASのトランザクション・コンテキストを制御するための新しいインターフェースUOWManagerが使用できます。Seasar2などのフレームワーク製品は,このインターフェースを使用してトランザクション制御を行っています。
JTA/JTSで提供されているトランザクション機能
J2EEアプリケーションでトランザクションを実現するためには,JTA(Java Transaction API)、JTS(Java Transaction Service)という二つの仕様が定められています。JTSはトランザクションを管理するトランザクションマネージャーの仕様が定められ,JTAではトランザクションマネージャーがトランザクションを管理するために必要となるAPIが定義されています(図1)。
図 1. JTA/JTSで使用されるインターフェース
UserTransactionインターフェースは,ユーザーのアプリケーションが直接トランザクションを制御する際に利用されるもので,トランザクションの開始,Commit/Rollbackなどを行うことができます。
TransactionManagerインターフェースはEJBコンテナなどがトランザクションの制御を行うために利用するAPIです。TransactionManagerは,直接アプリケーション開発者が利用することを意図してデザインされていません。WASでもトランザクションマネージャーを操作するTransactionManagerは公開されていません。
XAResourceインターフェースは,トランザクションマネージャーがデータベースやメッセージングシステムなどのリソースマネージャーを操作するために利用します。
TransactionManagerインターフェースで提供されている機能のなかには,UserTransactionインターフェースでは提供されていないものがいくつかあります。そのひとつがトランザクションのsuspend/resumeの機能です。これらは,現在実行中のトランザクションを一時停止して別のトランザクションを開始するため,つまりネストした(入れ子になった)トランザクションを実現するために提供されています。これらはEJBのトランザクション属性としてRequiresNewを指定した際などに利用されています。
このような複数のトランザクションを扱うような処理は,公開されているUserTransactionだけでは実現することができません。
UOWManagerによるトランザクション・コンテキストの作成
Seasar2などのフレームワークでは,独自にさまざまな方法でトランザクションの制御を行うことができるようになっています。これらのフレームワークがWASのトランザクションマネージャーの機能を安全に使用するために,WASのV6.0.2.19またはV6.1.0.9以降では,UOWManagerを利用したトランザクション・コンテキスト制御機能が提供されています。この機能を利用すると,これらのフレームワークが安全にトランザクションの作業単位(UOW)を開始したりすることができるようになります。
UOWManagerは,WAS上ではJNDIをつかって取得することができます。
Context ic = new InitialContext();
UOWManager ut = (UOWManager) ic.lookup("java:comp/websphere/UOWManager");
|
UOWManagerのもとで処理を実行するには,UOWActionインターフェースを実装したクラスを作成し,そのrunメソッド内に必要な処理を記述します。このクラスのインスタンスをUOWManagerのrunUnderUOWメソッドで実行します。匿名クラスを使用すると以下のようにかけます。
try {
uowManager.runUnderUOW(UOW_TYPE_GLOBAL_TRANSACTION, false,
new UOWAction() {
public void run() throws Exception {
<< ここにトランザクション処理を記述する >>
}
});
} catch (UOWActionException uowae) {
// 処理でチェック例外が発生した場合に呼ばれる
}
|
このようにすることで,runUnderUOWによって実行される処理は,別のトランザクションとして実行されるようになります(図2)。
図 2. UOWManagerによる別トランザクションでの処理
runUnderUOWは三つの引数をとります。一つ目の引数はUOWActionを実行するトランザクションの種類の指定で,UOWSynchronizationRegistryで定義された定数のうちひとつを指定します。トランザクションの種類は,グローバルトランザクション,ローカルトランザクションとActivitySessionが指定できます(ActivitySessionはWASで提供される独自のトランザクションタイプで,ローカルトランザクションやグローバルトランザクションを含んだ,より粒度のおおきなトランザクションとして利用できます)。別の種類のトランザクションが実行されている場合には,それが一時的に停止されて,新しいトランザクションが開始されます。同じ種類のトランザクションが実行されていた場合の挙動を指定するのが二つ目の引数です。trueの場合には既存のトランザクションを引き継ぐことが可能で,falseの場合は新規のトランザクションが開始されます。三つ目の引数は実行するUOWActionです。
UOWManagerによるトランザクションの同期処理
UOWManagerが拡張しているUOWSynchronizationRegistryインターフェースは,JTA 1.1で提供されるTransactionSynchronizationRegistryと同等の機能も提供しています。たとえば,現在実行中のトランザクション・コンテキストにリソースをマップする機能,フレームワークなどがトランザクションの同期をおこなうための機能などを提供します。JTA 1.1は,Java EE 5の仕様の一部ですが,WAS V6はこの機能を先行して実装しています。
トランザクションの同期処理を行う場合には,UOWSynchronizationRegistryインターフェースで提供されるregisterInterposedSynchronizationメソッドを使用します。このメソッドはSynchronizationインターフェースを実装したクラスのインスタンスを引数として受け取ります。このメソッドで登録されたオブジェクトは,2-Phase Commit処理が始まる直前にbeforeCompletion()が,Commit処理が完了したあとにafterCompletion(int status)メソッドが,トランザクションマネージャーから呼び出されます。(図3)。
図 3. UOWManagerによるトランザクションの同期処理
UOWSynchronizationRegistryは,UOWManagerとして取得したものを使用することも可能ですし,またJNDIを使用して直接取得することもできます。
Context ic = new InitialContext();
UOWSynchronizationRegistry usr = (UOWSynchronizationRegistry)
ic.lookup("java:comp/websphere/UOWSynchronizationRegistry");
|
以下に匿名クラスを用いたコードの例をあげます。
usr.registerIterposedSynchronization(new Synchronization() {
public void beforeCompletion() {
// 2-Phase Commitの前に行う処理
}
public void afterCompletion(int status)
// 2-Phase Commitの後に行う処理
}
});
|
これにより,たとえば直接トランザクションマネージャーが管理できない(XAResouceによる操作ができない)リソースについてもトランザクションに参加させることが可能となります。beforeCompletion()にPrepareに相当する処理を,afterCompletion()には引数に応じてCommit/Rollbackに相当する処理を記述することにより,トランザクション中で処理されるリソースと同期してリソースを更新することが可能となります。
最後に
フレームワークがPOJOによるトランザクション処理を実現するためには,これらの機能が内部で使用されています。IBMでは,Seasar2など主要なフレームワークのプロジェクトチームと連携し,これらのフレームワークがWASの機能を活用できるようにサポートを行っています。
著者について  | |  | 2000年よりソフトウェア事業で WebSphere Application Server の技術者として日本でのセールス活動に携わる。日本語での WAS の技術文書の執筆なども多くおこなっている。 |
記事の評価
|