Oracle® Fusion Middleware Oracle WebLogic Server Tuxedo Connector プログラマーズ ガイド 11g リリース 1 (10.3.1) B55532-01 |
|
戻る |
次へ |
以下の節では、グローバル トランザクションの概要とそれらをアプリケーションで定義および管理する方法について説明します。
グローバル トランザクションは、2 つ以上のリソース マネージャのある作業、および 1 つの論理単位として扱われる 2 つ以上の物理サイトにまたがる作業を実行するトランザクションです。グローバル トランザクションは常に、次の 4 つのプロパティによって分類された特定のシーケンスの操作として扱われます。
原子性 : すべての部分が正常に実行されるか、またはまったく影響しないかのいずれか。
一貫性 : 操作は、リソースを 1 つの一貫性のある状態から別の一貫性のある状態へと正確に変換するよう実行される。
隔離性 : 同じトランザクションの他のプロセスがそのデータにアクセス可能であっても、中間結果は他のトランザクションにアクセスできない。
持続性 : 完了したシーケンスのすべての結果は、いかなる障害によっても変更できない。
Oracle WebLogic Tuxedo Connector は、トランザクションの管理に Java Transaction API (JTA) を使用します。
JTA には、3 つのタイプのトランザクション インタフェースがあります。
Transaction
TransactionManager
UserTransaction
Transaction
インタフェースは、対象となる Transaction オブジェクトのトランザクションに対して実行される操作を許可します。トランザクション オブジェクトは、作成された各グローバル トランザクションに対応して作成されます。Transaction
インタフェースは、リソースの取得、登録の同期、およびトランザクション完了操作やステータス クエリ操作を実行するために使用します。
TransactionManager
インタフェースによって、アプリケーション サーバはアプリケーションの代わりにトランザクション境界区分のトランザクション マネージャと通信できるようになります。TransactionManager
インタフェースは、コンテナ管理の EJB コンポーネントの代わりにトランザクション マネージャと通信するために使用します。
トランザクションは、クライアントまたはサーバ プロセスのいずれかで定義できます。トランザクションは、3 つの部分で構成されます。3 つの部分とは、開始ポイント、トランザクション モードのプログラム文、および終了ポイントです。
トランザクションを明示的に定義するには、begin()
メソッドを呼び出します。呼び出しを行う同じプロセスである開始プロセスは、commit()
、setRollbackOnly()
または rollback()
を呼び出すことによって終了を行うプロセスにもなる必要があります。トランザクション区切り記号間で呼び出されるサービス サブルーチンは、現在のトランザクションの一部となります。
注意 : setTransactionTimeout() をあまり大きい値に設定すると、システム検出やエラーのレポートが遅延します。タイムアウト値は、適切な時間内でサービス リクエストへの応答を行ったり、ネットワーク障害などの問題が発生したトランザクションを終了したりするために使用します。プロダクション環境では、システム ロードおよびデータベース競合によって起こると予想される遅延に対応するよう、タイムアウト値を調整します。 |
トランザクションは、begin()
の呼び出しによって開始されます。タイムアウト値を指定するには、begin()
文の前に setTransactionTimeout(int seconds)
文を指定します。
Oracle Tuxedo にトランザクションを伝播するには、次の操作を実行する必要があります。
JNDI で、TuxedoConnectionFactory オブジェクトをルックアップします。
getTuxedoConnection() を使用して、TuxedoConnection オブジェクトを取得します。
トランザクションは、commit()
、rollback()
、または setRollbackOnly()
の呼び出しによって終了されます。commit()
が正常に復帰すると、現在のトランザクションでリソースに対して行われた変更はすべて永続的なものとなります。commit()
が正常に実行されるには、次の 2 つの条件が満たされている必要があります。
呼び出しプロセスは、begin()
でトランザクションを開始した同じプロセスでなければならない。
呼び出しプロセスに、未処理のトランザクション応答が存在してはならない。
いずれかの条件が真でない場合、この呼び出しは失敗し、例外が送出されます。
setRollbackOnly()
および rollback()
は、異常が発生したことを示し、すべての記述子を元の状態にロールバックする場合に使用します。
トランザクションをロールバックする前に何らかの処理やクリーンアップが必要な場合は、setRollbackOnly()
を使用します。
トランザクションをロールバックする前に何の処理もクリーンアップも不要な場合は、rollback()
を使用します。
トランザクション モード中は、トランザクションを正常に完了させるために特定のルールに従う必要があります。トランザクション モード中に注意すべき基本的なルールは、次のとおりです。
begin()
でトランザクションを開始した後で、TuxedoConnection オブジェクトを使用して、Oracle Tuxedo にトランザクションを伝播する必要があります。
tpterm() はオブジェクトへの接続を終了し、このオブジェクトでは今後操作を行わないようにします。
同じトランザクションの参加コンポーネントであるプロセスは、それらのリクエストへの応答を要求する必要があります。
応答を必要としないリクエストは、tpacall() の flags パラメータが TPNOREPLY に設定されている場合のみ実行できます。
サービスは、commit()
を呼び出す前にすべての非同期トランザクション応答を取得する必要があります。
開始プロセスは、begin()
を呼び出す前にすべての非同期トランザクション応答を取得する必要があります。
取り出す必要のある非同期応答には、トランザクションの非参加コンポーネントから期待される応答 (つまり応答ではなくトランザクションを抑制する tpacall() で行われたリクエストに対して期待される応答) が含まれます。
トランザクションがタイムアウトされず、「アボートのみ」にマーク付けされている場合は、通信の結果として実行された処理がトランザクションのロールバック後に永続化するよう、以後の通信を TPNOTRAN フラグを設定して実行する必要があります。
トランザクションがタイムアウトされた場合は次のとおりです。
タイムアウトされた呼び出しの記述子は無効となり、それ以後の記述子の参照には、TPEBADDESC が返されます。
未処理の記述子の tpgetrply() または tprecv() の以後の呼び出しは、tperrono
を TPETIME に設定することによってグローバルな状態のトランザクション タイムアウトを返します。
TPNOREPLY|
TPNOBLOCK|
TPNOTRAN に設定された tpacall() の flags パラメータで非同期呼び出しを行うことができます。
タイムアウト以外の理由でトランザクションが「アボートのみ」にマーク付けされると、tpgetrply() の呼び出しは、その呼び出しのローカルな状態を示すものをすべて返します。つまり、ローカルな状態を示す成功コードまたはエラー コードのいずれかを返すことができます。
tpgetrply() で返信を取り込むために使用された記述子は無効になり、それ以後の参照では TPEBADDESC が返されます。
tpsend() または tprecv() でエラー状態を報告するために使用された記述子は無効になり、それ以後の参照では TPEV_DISCONIMM が返されます。
トランザクションがアボートされると、未処理のすべてのトランザクション呼び出し記述子 (TPNOTRAN フラグなしで実行) が停滞状態となり、以後それらに対する参照には TPEBADDESC が返されます。
Oracle WebLogic Tuxedo Connector では、ロード バランシング時に、特定のトランザクション ID の呼び出しすべてが、特定のサーバ インスタンスにルーティングされるわけではありません。ロード バランシングは呼び出し単位で行われます。
次に、トランザクションのサンプル コードを示します。
コード リスト 5-1 サンプル トランザクション コード
public class TransactionSampleBean implements SessionBean { ..... public int transaction_sample () { int ret = 0; try { javax.naming.Context myContext = new InitialContext(); TransactionManager tm = (javax.transaction.TransactionManager) myContext.lookup("javax.transaction.TransactionManager"); // トランザクションを開始する tm.begin (); TuxedoConnectionFactory tuxConFactory = (TuxedoConnectionFactory) ctxt.lookup("tuxedo.services.TuxedoConnection"); // このトランザクションの一部になるローカルの // JDBC/XA データベース操作をここで実行できる。 ..... // 注意 1 : Tuxedo の呼び出しをトランザクションの一部 // にする必要がある場合は、Tuxedo 接続を // トランザクションの開始後にのみ取得する // 注意 2 : トランザクションの開始前に Tuxedo // 接続を取得すると、その Tuxedo 接続からの // すべての呼び出しがトランザクションのスコープ外 // になる TuxedoConnection myTux = tuxConFactory.getTuxedoConnection(); // tpcall を実行する。この tpcall がトランザクションの一部です。 TypedString depositData = new TypedString("somecharacters,5000.00"); Reply depositReply = myTux.tpcall("DEPOSIT", depositData, 0); // TPNOTRAN フラグを設定することによって、 // トランザクションの一部ではない tpcall を実行することも // できる (たとえば試行されたすべての処理のロギングなど) TypedString logData = new TypedString("DEPOSIT:somecharacters,5000.00"); Reply logReply = myTux.tpcall("LOGTRAN", logData, ApplicationToMonitorInterface.TPNOTRAN); // Tuxedo 接続が用済みになり、tpterm を実行する myTux.tpterm (); // トランザクションをコミットする... tm.commit (); // 注意 : このトランザクションで使用されている // TuxedoConnection オブジェクトは、 // TPNOTRAN フラグが設定されている場合のみトランザクション後も使用できる。 } catch (NamingException ne) { System.out.println ("ERROR: Naming Exception looking up JNDI: " + ne); ret = -1; } catch (RollbackException re) { System.out.println("ERROR: TRANSACTION ROLLED BACK: " + re); ret = 0; } catch (TPException te) { System.out.println("ERROR: tpcall failed: TpException: " + te); ret = -1; } catch (Exception e) { log ("ERROR: Exception: " + e); ret = -1; } return ret; }