ページの先頭行へ戻る
Interstage Application Server V13.0.0 GlassFish 設計・構築・運用ガイド
FUJITSU Software

2.15.1 ローカルトランザクションとグローバルトランザクション

JTAトランザクションには、ローカルトランザクションとグローバルトランザクションが存在します。複数のリソースに対する処理の一貫性を保証するには、グローバルトランザクションを使用する必要があります。しかし、2フェーズコミットプロトコルによる性能オーバーヘッドがかかるため、できる限り単一のリソースだけを使用するように設計して、ローカルトランザクションを使用することをお勧めします。

ローカルトランザクション

ローカルトランザクションには、1つのリソースだけが含まれます。トランザクションの有効範囲は、リソース自体でローカルに管理されます。ローカルトランザクションでは、1フェーズコミットプロトコルが使用されます。また、ローカルトランザクションの場合、1つのプロセス内でトランザクション制御されることを必要とします。

グローバルトランザクション

グローバルトランザクションでは、トランザクション内に複数のリソースが登録できます。例えば、グローバルトランザクションは、2つのデータベースを作業範囲とする場合に使用します。また、グローバルトランザクションの場合、複数のプロセス間でトランザクション制御できます。
グローバルトランザクションでは、2フェーズコミットプロトコルが使用されます。

ローカルトランザクションで動作する条件

ローカルトランザクションは1つの非XAリソースだけを含んでおり、トランザクションに参加するJakarta EEコンポーネントがすべて1つのプロセス内で実行されることを必要とします。1トランザクション範囲内で複数の非XAリソースが使用された場合、トランザクションはエラーとなります。

JDBCリソースが非XAリソースとして扱われる条件は以下です。

グローバルトランザクションで動作する条件

複数のリソースを管理するトランザクションまたは複数のプロセス間でトランザクションを管理する場合は、グローバルトランザクションとなります。グローバルトランザクションは、use-last-agent-optimizationプロパティがtrueの場合(デフォルトはtrue)、1つだけ非XAリソースを実行できます。それ以外の場合は、すべてXAである必要があります。use-last-agent-optimizationプロパティについては、「2.15.3 2フェーズコミットプロトコル」を参照してください。
トランザクション内で1つのXAリソースだけ使用した場合、リソース間の一貫性を保証する必要がないため1フェーズコミットプロトコルで処理されます。それ以外は、2フェーズコミットプロトコルで動作します。

グローバルトランザクションの制御が必要なケース

同一トランザクション範囲内で以下のようなリソースアクセスが発生した場合に、グローバルトランザクションでの制御が必要となります。

ケース1:複数のリソースマネージャにアクセスする場合

複数のリソースマネージャに同一トランザクション範囲内でアクセスする場合、グローバルトランザクションでの制御が必要となります。以下の例は、複数のデータベース(database A、database B、database C)が存在し、同一トランザクション範囲内でXとYというJakarta EEコンポーネントから各データベースにアクセスする例です。

以下の例のようにJMSのキュー(queue A)とデータベース(database B,database C)に、同一トランザクション範囲内でXとYというJakarta EEコンポーネントからアクセスした場合も同様です。

ケース2:メッセージの受信とリソースマネージャにアクセスする場合

メッセージの受信とリソースマネージャへのアクセスを同一トランザクション範囲内で行う場合、グローバルトランザクションでの制御が必要となります。以下の例は、キュー(queue A)からメッセージを受信し、同一トランザクション範囲内でXというJakarta EEコンポーネントからデータベース(database B、database C)にアクセスする例です。

ケース3:複数プロセス間でリソースマネージャにアクセスする場合

複数のプロセス(GlassFish Serverクラスター)で連携して同一トランザクション範囲内でリソースマネージャにアクセスする場合、グローバルトランザクションでの制御が必要となります。複数のリソースマネージャにアクセスしない場合においてもトランザクションを開始した状態で呼び出して別のプロセスでリソースマネージャにアクセスする場合には、グローバルトランザクションでの制御が必要となります。以下の例は、GlassFish Serverクラスター1のXというJakarta EEコンポーネントからデータベース(database A)にアクセスし、同一トランザクション範囲内でGlassFish Serverクラスター2のYというJakarta EEコンポーネントからデータベース(database B)にアクセスする例です。

ケース4:クライアントでトランザクション管理する場合

GlassFish Serverクラスターにアクセスするクライアントでトランザクションを開始し、そのトランザクション範囲内でリソースマネージャにアクセスする場合、グローバルトランザクションでの制御が必要となります。以下の例は、クライアントでトランザクションを開始(begin)して、GlassFish Serverクラスター1のXというJakarta EEコンポーネントからデータベース(database A)にアクセスし、同一トランザクション範囲内でGlassFish Serverクラスター2のYというJakarta EEコンポーネントからデータベース(database B)にアクセスする例です。

注意

  • トランザクション処理は非常に負荷のかかる制御が必要となるため、できる限りサーバー側でトランザクション処理するように設計してください。

  • 以下のケースの場合、トランザクションが開始された状態で呼び出されたプロセスでは、トランザクションを開始したプロセスに対してトランザクションに参加したことをIIOP通信により通知します。これによりトランザクションマネージャに対するトランザクションの完了要求(コミットもしくはロールバック)が実行されると、トランザクションに参加している各プロセスにもトランザクションの完了要求が通知されます。

    • 複数プロセス間でリソースマネージャにアクセスする場合

    • クライアントでトランザクション管理する場合

    このため、上記のケースではトランザクション制御を考慮してIIOP通信に関する各種設定をチューニングする必要があります。GlassFish Serverインスタンス間でトランザクションを連携する場合、トランザクションを開始して呼び出すGlassFish Serverインスタンスのスレッドプールの最大プールサイズを、トランザクションを開始するGlassFish Serverインスタンスのスレッドプールの最大プールサイズに加算して設定してください。最大プールサイズが不足していると、業務処理で利用するスレッドがスレッドプールを占有し、トランザクションの通知が実行できずに無応答状態となる場合があります。