データベース照会の実行

コラボレーションの実行時に、データベース (関連データベースなど) から情報を取得する必要があることがあります。データベースの情報を取得または変更するには、その表を照会します。照会は、データベースに送信して実行させる、通常は SQL (Structured Query Language) ステートメント形式の要求です。表 51 に、データベースでの照会の実行に関する手順を示します。

注:
WebSphere Business Integration Server Express がサポートする外部データベースには、Oracle シン・タイプ 4 ドライバーおよび WebSphere Business Integration Server Express ブランドの MS-SQL Server タイプ 4 ドライバーを介し、JDBC を使用してアクセスできます。


表 51. 照会の実行作業
照会の実行作業 詳細
1. データベースへの接続 (CwDBConnection オブジェクト) を取得します。 "接続の取得"
2. CwDBConnection オブジェクトを使用して、データベース内で照会の送信とトランザクションの管理を行います。 "照会の実行""トランザクションの管理"
3. 接続を解放します。 "接続の解放"

ヒント:
データベース照会の使用法の 1 つとして、待ち時間が長いサービス呼び出しの処理があります。コラボレーションは、処理時間が長いと予想されるサービス呼び出しを発行した後に、データベース接続を使用している実行コンテキストを保管してから終了します。サービス呼び出しからの実際の応答 (数時間または数日間後であることがあります) は、新しいイベントとして戻され、別のコラボレーションを起動します。これにより、データベースからの適切な実行コンテキストが復元され、ビジネス・プロセスの実行が再開されます。

接続の取得

データベースの照会を行うには、最初に BaseCollaboration クラスの getDBConnection() メソッドを使用してデータベースへの接続を取得する必要があります。

取得する接続を識別するには、この接続が含まれる接続プールの名前を指定します。

特定の接続プールのすべての接続は、同じデータベースに対して行われます。接続プール内の接続の数は、接続プール構成の一部として決定されます。照会対象のデータベースの接続が含まれる接続プールの名前を決定する必要があります。

要確認:
接続は、InterChange Server がブートされたとき、または新しい接続プールが動的に構成されたときに開かれます。このため、目的のデータベースに対する接続が含まれる接続プールは、接続を要求するコラボレーション・オブジェクトが実行される前に構成する必要があります。System Manager 内で接続プールを構成します。詳細については、「WebSphere InterChange Server システム・インプリメンテーション・ガイド」を参照してください。

図 77 では、getDBConnection() への呼び出しが、CustDBConnPool 接続プール内の接続に関連付けられたデータベースへの接続を取得します。

図 77. 接続プールからの接続の取得

CwDBConnection connection = getDBConnection("CustDBConnPool");
 

getDBConnection() 呼び出しは、connection 変数内の CwDBConnection オブジェクトを戻します。このオブジェクトを使用すると、接続に関連付けられたデータベースにアクセスできます。

ヒント:
getDBConnection() メソッドは、接続のトランザクション・プログラミング・モデルを指定できる追加形式を提供します。詳細については、"トランザクションの管理"を参照してください。

照会の実行

表 52 に、CwDBConnection クラスのメソッドを使用して SQL 照会を実行する方法を示します。

表 52. CwDBConnection メソッドの使用による SQL 照会の実行
照会のタイプ 説明 CwDBConnection メソッド
静的照会 SQL ステートメントは、テキストとしてデータベースに送信されます。 executeSQL()
準備済み照会 初回の実行後、SQL ステートメントは、コンパイルされた実行可能形式で保管されます。これにより、後続の実行時に、このプリコンパイル形式が使用できます。 executePreparedSQL()
ストアード・プロシージャー SQL ステートメントおよび条件ロジックが含まれるユーザー定義のプロシージャー executeSQL()executePreparedSQL() executeStoredProcedure()

静的照会の実行

executeSQL() メソッドは、静的照会を実行するためにデータベースへ送信します。

静的照会は、ストリングとしてデータベースに送信される SQL ステートメントです。このデータベースがこのストリングを解析し、結果の SQL ステートメントを実行します。このセクションでは、executeSQL() を使用して以下の種類の SQL 照会をデータベースに送信する方法について説明します。

データを戻す静的照会の実行 (SELECT)

SQL ステートメント SELECT は、1 つ以上の表のデータを照会します。SELECT ステートメントをデータベースに送信して実行させるには、SELECT のストリング表記を引き数として executeSQL() メソッドに指定します。例えば、executeSQL() への次の呼び出しは、customer 表から 1 列の値の SELECT を送信します。

connection.executeSQL(
    "select cust_id from customer where active_status = 1");
 

注:
前のコードで、connection 変数は、getDBConnection() メソッドへの前の呼び出しから取得した CwDBConnection オブジェクトです (図 77 を参照してください)。

また、executeSQL() メソッドの 2 番目の形式を使用して、パラメーターを持つ SELECT ステートメントを送信することもできます。例えば、executeSQL() に対する以下の呼び出しにより、前の例と同じ操作が行われます。ただし、この場合、アクティブ状況がパラメーターとして SELECT ステートメントに渡されます。

Vector argValues = new Vector();
  
 String active_stat = "1";
 argValues.add( active_stat );
 connection.executeSQL(
    "select cust_id from customer where active_status = ?", argValues);
 

SELECT ステートメントは、データベースの表からデータを行として戻します。

各行は、SELECT の WHERE 文節の条件と一致するデータの 1 行を示します。各行には、SELECT ステートメントが指定した列の値が含まれます。戻されたデータは、これらの行および列による 2 次元配列として表示できます。

ヒント:
SELECT ステートメントの構文は、アクセスする特定のデータベースに対して有効である必要があります。SELECT ステートメントの正確な構文については、データベース文書を確認してください。

戻されたデータにアクセスする手順は、以下のとおりです。

  1. 1 行のデータを取得します。
  2. 列の値を 1 つずつ取得します。

表 53 に、戻された照会データの行にアクセスするための CwDBConnection クラスのメソッドを示します。

表 53.
行にアクセスするための CwDBConnection メソッド
列にアクセスするための操作 CwDBConnection メソッド
行があるかどうかのチェック hasMoreRows()
1 行のデータを取得 nextRow()

hasMoreRows() メソッドを使用して、戻された行のループを制御します。 hasMoreRows()false を戻したら、行のループを終了します。1 行のデータを取得するには、nextRow() メソッドを使用します。このメソッドは、選択された列の値を Java Vector オブジェクトの要素として戻します。

これにより、Enumeration クラスを使用して、列の値に個別にアクセスできます。

Vector クラスと Enumeration クラスの両方が java.util パッケージ内にあります。

表 54 に、戻された照会行の列にアクセスするための Java メソッドを示します。

表 54. 列の値にアクセスするための Java メソッド
列にアクセスするための操作 Java メソッド
列の数の確認 Vector.size()
Enumeration に対する Vector のキャスト Vector.elements()
列があるかどうかのチェック Enumeration.hasMoreElements()
1 列のデータの取得 Enumeration.nextElement()

hasMoreElements() メソッドを使用して、列の値のループを制御します。 hasMoreElements()false を戻したら、列のループを終了します。列の値を取得するには、nextElement() メソッドを使用します。

以下のコード・サンプルは、顧客情報が格納されたデータベースへの接続である CwDBConnection クラスのインスタンスを取得します。次に、SELECT ステートメントを実行します。これにより、顧客 ID 20987 の会社名「CrossWorlds」の単一列が含まれる 1 行が戻されます。

CwDBConnection connectn = null;
 Vector theRow = null;
 Enumeration theRowEnum = null;
 String theColumn1 = null;
  
 try
    {
    // Obtain a connection to the database
    connectn = getDBConnection("sampleConnectionPoolName");
    }
  
 catch(CwDBConnectionFactoryException e)
    {
    System.out.println(e.getMessage());
    throw e;
    }
  
 // Test for a resulting single-column, single-row, result set
 try {
    // Send the SELECT statement to the database
    connectn.executeSQL(
       "select company_name from customer where cust_id = 20987");
  
    // Loop through each row
    while(connectn.hasMoreRows())
       {
       // Obtain one row
       theRow = connectn.nextRow();
       int length = 0;
       if ((length = theRow.size())!= 1)
          {
          return methodName + "Expected result set size = 1," +
             " Actual result state size = " + length;
          }
  
       // Get column values as an Enumeration object
       theRowEnum = theRow.elements();
  
       // Verify that column values exist
       if (theRowEnum.hasMoreElements())
          {
          // Get the column value
          theColumn1 = (String)theRowEnum.nextElement();
          if (theColumn1.equals("CrossWorlds")==false)
             {
             return "Expected result = CrossWorlds,"
                + " Resulting result = " + theColumn1;
             }
          }
       }
    }
  
 // Handle any exceptions thrown by executeSQL()
 catch(CwDBSQLException e)
    {
    System.out.println(e.getMessage());
    }
 

以下の例は、複数の行を戻す SELECT ステートメントのコード・フラグメントを示します。各行には、顧客 ID および関連会社名の 2 列が含まれます。

CwDBConnection connectn = null;
 Vector theRow = null;
 Enumeration theRowEnum = null;
 Integer theColumn1 = 0;
 String theColumn2 = null;
  
 try
    {
    // Obtain a connection to the database
    connectn = getDBConnection("sampleConnectionPoolName");
    }
  
 catch(CwDBConnectionFactoryException e)
    {
    System.out.println(e.getMessage());
    throw e;
    }
  
 // Code fragment for multiple-row, multiple-column result set.
 // Get all rows with the specified columns, where the
 // specified condition is satisfied
 try
    {
    connectn.executeSQL(
 "select cust_id, company_name from customer where active_status = 1");
  
    // Loop through each row
    while(connectn.hasMoreRows())
       {
       // Obtain one row
       theRow = connectn.nextRow();
  
       // Obtain column values as an Enumeration object
       theRowEnum = theRow.elements();
       int length = 0;
       if ((length = theRow.size()) != 2)
       {
          return "Expected result set size = 2," +
             " Actual result state size = " + length;
       }
       // Verify that column values exist
       if (theRowEnum.hasMoreElements())
          {
          // Get the column values
          theColumn1 =
             ((Integer)theRowEnum.nextElement()).intValue();
          theColumn2 = (String)theRowEnum.nextElement();
          }
       }
    }
 catch(CwDBSQLException e)
    {
    System.out.println(e.getMessage());
    }
 

注:
SELECT ステートメントは、データベースの内容を変更しません。したがって、通常、SELECT ステートメントに対してトランザクション管理は実行しません

データを変更する静的照会の実行

データベースの表のデータを変更する SQL ステートメントには、以下が含まれます。

これらのステートメントの 1 つを静的照会としてデータベースに送信して実行させるには、ステートメントのストリング表記を引き数として executeSQL() メソッドに指定します。例えば、executeSQL() に対する以下の呼び出しにより、現在の接続に関連付けられたデータベースの abc 表に対する 1 行の INSERT が送信されます。

connection.executeSQL("insert into abc values (1, 3, 6)");
 

注:
前のコードで、connection 変数は、getDBConnection() メソッドへの前の呼び出しから取得した CwDBConnection オブジェクトです。

UPDATE または INSERT ステートメントの場合、getUpdateCount() メソッドを使用して、変更または追加されたデータベースの表の行数を確認できます。

要確認:
INSERT、UPDATE、および DELETE ステートメントはデータベースの内容を変更するため、これらのステートメントに対してトランザクション管理の必要性を評価することを推奨します。

詳細については、"トランザクションの管理"を参照してください。

静的ストアード・プロシージャーの実行

以下の両方の 条件が満たされていれば、executeSQL() メソッドを使用してストアード・プロシージャー呼び出しを実行できます。

詳細については、"ストアード・プロシージャーの実行"を参照してください。

準備済み照会の実行

executePreparedSQL() メソッドは、準備済み照会を実行するためにデータベースへ送信します。

準備済み照会は、データベースによる実行可能形式にすでにプリコンパイルされている SQL ステートメントです。executePreparedSQL() は、初めてデータベースに照会を送信するときに照会をストリングとして送信します。データベースは、この照会を受信し、文字列を解析して実行可能形式にコンパイルし、その結果の SQL ステートメントを実行します (executeSQL() に対する操作と同様)。ただし、データベースはこの SQL ステートメントのコンパイル済み形式を executePreparedSQL() に戻し、このメソッドがこのステートメントをメモリーに保管します。このコンパイル済み SQL ステートメントを、準備済みステートメントと呼びます。

これと同じ照会が後で実行されるときには、executePreparedSQL() は、この照会に対して準備済みステートメントがすでに存在するかどうかを最初にチェックします。準備済みステートメントが存在する場合、executePreparedSQL() は、照会ストリングの代わりにこれをデータベースに送信します。この後にこの照会が実行される場合、データベースはストリングを解析して準備済みステートメントを実行する必要がないため、処理がより効率的になります。

executePreparedSQL() を使用して、以下の種類の SQL 照会をデータベースに送信できます。

データを戻す準備済み照会の実行 (SELECT)

同じ SELECT ステートメントを複数回実行する必要がある場合は、executePreparedSQL() を使用してステートメントのプリコンパイル・バージョンを作成します。SELECT ステートメントを準備する場合は、以下の点に注意する必要があります。

データを変更する準備済み照会の実行

同じ INSERT、UPDATE、または DELETE ステートメントを複数回実行する必要がある場合は、executePreparedSQL() を使用してステートメントのプリコンパイル・バージョンを作成します。再実行する SQL ステートメントは、実行するたびに正確に同じでなくても、準備済みステートメントの利点を利用できます。SQL ステートメントのパラメーターを使用して、ステートメントの実行のたびに情報を動的に提供できます。

図 78 のコード・フラグメントは、employee 表に 50 行を挿入します。executePreparedSQL() は、初めて呼び出されるときに、INSERT ステートメントのストリング・バージョンをデータベースに送信します。これにより、このデータベースは、これを解析し、実行し、その実行可能形式である準備済みステートメントを戻します。INSERT ステートメントが実行される次の 49 回 (すべての INSERT の実行が成功であると仮定) では、executePreparedSQL() は、準備済みステートメントが存在することを認識し、この準備済みステートメントをデータベースに送信して実行させます。

図 78. 準備済みステートメントに対する引き数値の渡し

CwDBConnection connection;
 Vector argValues = new Vector();
  
 argValues.setSize(2);
  
 int emp_id = 1;
 int emp_id = 2000;
  
 for (int = 1; i < 50; i++)
    {
    argValues.set(0, new Integer(emp_id));
    argValues.set(1, new Integer(emp_num));
  
    try
       {
       // Send the INSERT statement to the database
       connection.executePreparedSQL(
 "insert into employee (employee_id, employee_number) values (?, ?)",
           argValues);
  
       // Increment the argument values
       emp_id++;
       emp_num++
       }
  
    catch(CwDBSQLException e)
       {
       System.out.println(e.getMessage());
       }
    }
 

ヒント:
通常、INSERT ステートメントの準備済みバージョンの実行により、アプリケーションのパフォーマンスが向上しますが、アプリケーションのメモリー・フットプリントは増加します。

データベースを変更する SQL ステートメントを再実行する場合、トランザクション・プログラミング・モデルに応じてトランザクションを処理する必要があります。詳細については、"トランザクションの管理"を参照してください。

注:
単純化のため、図 78 のコードにはトランザクション管理が含まれていません

準備済みストアード・プロシージャーの実行

以下の両方の 条件が満たされていれば、executePreparedSQL() メソッドを使用してストアード・プロシージャー呼び出しを実行できます。

詳細については、"ストアード・プロシージャーの実行"を参照してください。

ストアード・プロシージャーの実行

ストアード・プロシージャーは、SQL ステートメントおよび条件ロジックが含まれるユーザー定義のプロシージャーです。ストアード・プロシージャーは、データと共にデータベースに格納されます。

注:
新しい関係を作成する場合、Relationship Designer は、各関係表を保守するためにストアード・プロシージャーを作成します。

表 55 に、ストアード・プロシージャーを呼び出すための CwDBConnection クラスのメソッドを示します。

表 55.
ストアード・プロシージャーを呼び出すための CwDBConnection メソッド
ストアード・プロシージャーを呼び出す方法 CwDBConnection メソッド 使用
データベースに CALL ステートメントを送信し、ストアード・プロシージャーを実行します。 executeSQL() OUT パラメーターがなく一度のみ 実行するストアード・プロシージャーを呼び出す方法。

executePreparedSQL() OUT パラメーターがなく複数回 実行するストアード・プロシージャーを呼び出す方法。
ストアード・プロシージャーの名前およびパラメーターの配列を指定し、プロシージャー呼び出しを作成し、これをデータベースに送信して実行させます。 executeStoredProcedure() OUT パラメーターがある任意のストアード・プロシージャーを呼び出す方法。

注:
JDBC メソッドを使用して、ストアード・プロシージャーを直接実行できます。ただし、CwDBConnection クラスが提供するインターフェースはより簡単であり、また、データベース・リソースを再利用するので、実行効率が向上します。CwDBConnection クラス内のメソッドを使用して、ストアード・プロシージャーを実行することができます。

ストアード・プロシージャーは、1 行または複数行の形式でデータを戻すことができます。

この場合、同じ Java メソッド (hasMoreRows()nextRow() など) を使用して、SELECT ステートメントによって戻されたデータの場合と同じように、戻された照会結果の行にアクセスします。

詳細については、"データを戻す静的照会の実行 (SELECT)"を参照してください。

表 55 のように、どのメソッドを使用してストアード・プロシージャーを呼び出すかは、以下によって決まります。

以下のセクションでは、executeSQL() メソッドと executeStoredProcedure() メソッドを使用してストアード・プロシージャーを呼び出す方法を説明します。

OUT パラメーターがないストアード・プロシージャーの呼び出し

OUT パラメーターがない ストアード・プロシージャーを呼び出すには、CwDBConnection の以下のメソッドのいずれかを使用できます。

これらいずれかのメソッドを使用してストアード・プロシージャーを呼び出すには、ストアード・プロシージャーおよび引き数を含む CALL ステートメントのストリング表記をメソッドの引き数として指定します。

図 79 では、executeSQL() への呼び出しが、setOrderCurrDate() ストアード・プロシージャーを実行するための CALL ステートメントを送信します。

図 79. executeSQL() でのストアード・プロシージャーの呼び出し

connection.executeSQL("call setOrderCurrDate(345698)");
 

図 79 で、connection 変数は、getDBConnection() メソッドへの前の呼び出しから取得した CwDBConnection オブジェクトです。executeSQL() を使用して、setOrderCurrDate() ストアード・プロシージャーを実行できます。これは、その単一引き数が IN パラメーターである、つまり、その値がストアード・プロシージャーのみ に送信されるためです。このストアード・プロシージャーには OUT パラメーターがありません

パラメーター配列を受け入れる executeSQL() または executePreparedSQL() の形式を使用して、その引き数値をストアード・プロシージャーに渡すことができます。ただし、これらのメソッドを使用して、OUT パラメーターを使用するストアード・プロシージャーを呼び出すことはできません。このようなストアード・プロシージャーを実行するには、executeStoredProcedure() を使用する必要があります。詳細については、"executeStoredProcedure() でのストアード・プロシージャーの呼び出し"を参照してください。

注:
CwDBConnection .executeSQL() メソッドを使用して ODBC を介して Oracle ストアード PL/SQL オブジェクトを呼び出す場合は、匿名 PL/SQL ブロックを使用します。以下は、受け入れ可能なフォーマットを示します (ストアード・プロシージャー名は myproc です)。
connection.executeSQL("begin myproc(...); end;");
 

executeStoredProcedure() でのストアード・プロシージャーの呼び出し

executeStoredProcedure() メソッドは、OUT パラメーターを使用するストアード・プロシージャーを含む、任意のストアード・プロシージャーを実行できます。このメソッドは、executePreparedSQL() の場合と同じように、ストアード・プロシージャー呼び出しに対する準備済みステートメントを保管します。このため、executeStoredProcedure() は、複数回実行されるストアード・プロシージャー呼び出しのパフォーマンスを向上できます。

executeStoredProcedure() メソッドを使用してストアード・プロシージャーを呼び出す手順は、以下のとおりです。

  1. 実行するストアード・プロシージャーの名前を String として指定します。
  2. CwDBStoredProcedureParam オブジェクトの Vector パラメーター配列を構築します。このオブジェクトは、各ストアード・プロシージャー・パラメーターのイン/アウト・パラメーター・タイプおよび値を提供します。

パラメーターは、ストアード・プロシージャーに対して、またはストアード・プロシージャーから送信できる値です。

パラメーターのイン/アウト・タイプにより、ストアード・プロシージャーがパラメーター値を使用する方法が決まります。

CwDBStoredProcedureParam オブジェクトは、ストアード・プロシージャーの単一パラメーターを示します。表 56 は、CwDBStoredProcedureParam オブジェクトに含まれるパラメーター情報と、このパラメーター情報を検索および設定するメソッドを示します。


表 56. CwDBStoredProcedureParam オブジェクトのパラメーター情報
パラメーター情報 CwDBStoredProcedureParam メソッド
パラメーター値 getValue()
パラメーターのイン/アウト・タイプ getParamType()

executeStoredProcedure() メソッドを使用してストアード・プロシージャーにパラメーターを渡す手順は、以下のとおりです。

  1. パラメーター情報を保持するための CwDBStoredProcedureParam オブジェクトを作成します。

    CwDBStoredProcedureParam() コンストラクターを使用して、新規 CwDBStoredProcedureParam オブジェクトを作成します。

    このコンストラクターに以下のパラメーター情報を渡すことにより、オブジェクトを初期化します。

  2. 各ストアード・プロシージャー・パラメーターに対してステップ 1 を繰り返します。
  3. すべてのストアード・プロシージャー・パラメーターを保持するために、十分な要素を備えた Vector オブジェクトを作成します。
  4. 初期化した CwDBStoredProcedureParam オブジェクトをパラメーター Vector オブジェクトに追加します。

    Vector クラスの addElement() メソッドまたは add() メソッドを使用して、CwDBStoredProcedureParam オブジェクトを追加します。

  5. すべての CwDBStoredProcedureParam オブジェクトを作成し、これらを Vector パラメーター配列に追加したら、このパラメーター配列を 2 番目の引き数として executeStoredProcedure() メソッドに渡します。

    executeStoredProcedure() メソッドは、ストアード・プロシージャーおよびそのパラメーターをデータベースに送信して実行させます。

例えば、以下のように、データベースに get_empno() ストアード・プロシージャーが定義されているとします。

create or replace procedure get_empno(emp_id IN number,
       emp_number OUT number) as
    begin
       select emp_no into emp_number
       from emp
       where emp_id = 1;
    end;
 

この get_empno() ストアード・プロシージャーには、次の 2 つのパラメーターがあります。

図 80 は、executeStoredProcedure() メソッドを使用して get_empno() ストアード・プロシージャーを実行し、65 という従業員 ID の従業員番号を取得します。

図 80. get_empno() ストアード・プロシージャーの実行

CwDBConnection connectn = null;
  
 try
    {
    // Get database connection
    connectn = getDBConnection("CustomerDBPool");
  
    // Create parameter Vector
    Vector paramData = new Vector(2);
  
    // Create IN parameter for the employee id and add to parameter
    // vector
    paramData.add(
       new CwDBStoredProcedureParam(PARAM_IN, new Integer(65)));
  
    // Create dummy argument for OUT parameter and add to parameter
    // vector
    paramData.add(
       new CwDBStoredProcedureParam(PARAM_OUT, new Integer(0));
  
    // Call the get_empno() stored procedure
    connectn.executeStoredProcedure("get_empno", paramData);
  
    // Get the result from the OUT parameter
    CwDBStoredProcedureParam outParam =
       (CwDBStoredProcedureParam) paramData.get(1);
    int emp_number = ((Integer) outParam.getValue().Intvalue();
    }
 

ヒント:
Java Vector オブジェクトは、ゼロ・ベースの配列です。前のコードでは、Vector 配列がゼロ・ベースであるため、Vector パラメーター配列からこの OUT パラメーターの値にアクセスするために、get() 呼び出しは、索引値 1 を指定します。

ストアード・プロシージャーは、そのパラメーターを SQL データ型として処理します。SQL および Java データ型は同一ではない ため、executeStoredProcedure() メソッドは、これら 2 つのデータ型間でパラメーター値を変換する必要があります。IN パラメーターの場合、executeStoredProcedure() は、パラメーター値を Java データ型から SQL データ型に変換します。OUT パラメーターの場合、executeStoredProcedure() は、パラメーター値を SQL データ型から Java データ型に変換します。

executeStoredProcedure() メソッドは、JDBC データ型を内部で使用し、ストアード・プロシージャーに送受信されるパラメーター値を保持します。JDBC は、java.sql.Types クラスで汎用 SQL タイプの ID の集合を定義します。

これらのタイプは、最も一般的に使用される SQL タイプを示します。また、JDBC には、JDBC タイプから Java データ型への標準マッピングも用意されています。例えば、通常、JDBC INTEGER は Java int タイプにマッピングされます。 executeStoredProcedure() メソッドは、表 57 に示されているマッピングを使用します。

表 57.
Java データ型と JDBC データ型の間のマッピング
Java データ型 JDBC データ型
String CHAR、VARCHAR、または LONGVARCHAR
Integer、int INTEGER
Long BIGINT
Float、float REAL
Double、double DOUBLE
java.math.BigDecimal NUMERIC
Boolean、boolean BIT
java.sql.Date DATE
java.sql.Time TIME
java.sql.Timestamp TIMESTAMP
java.sql.Clob CLOB
java.sql.Blob BLOB
byte[] BINARY、VARBINARY、または LONGVARBINARY
Array ARRAY
Struct STRUCT

トランザクションの管理

トランザクションは、1 単位として実行される操作ステップの集合です。

トランザクション内で実行されるすべての SQL ステートメントは、1 単位として成功または失敗します。このセクションでは、トランザクションの管理に関する以下の情報について説明します。

トランザクション・プログラミング・モデルの決定

トランザクションに対するデータベース操作の実行ステップのグループ化は、トランザクション・ブラケットと呼ばれます。各接続には、以下のトランザクション・プログラミング・モデルの 1 つが関連付けられます。

コラボレーション・オブジェクトは実行時に、獲得する各接続に対して使用するトランザクション・プログラミング・モデルを決定します。デフォルトでは、コラボレーション・オブジェクトは、獲得するすべての 接続により、そのトランザクション・プログラミング・モデルとして暗黙的なトランザクション・ブラケットが使用されることを前提としています。デフォルトのトランザクション・プログラミング・モデルは、表 58 の任意の方法を使用してオーバーライドできます。

表 58. 接続のトランザクション・プログラミング・モデルのオーバーライド
オーバーライドするトランザクション・プログラミング・モデル 実行するアクション
特定のコラボレーション・オブジェクトによって取得される すべての接続に対する 異なるトランザクション・プログラミング・モデルの指定 System Manager の「Collaboration Properties」ダイアログの「暗黙的なデータベース・トランザクション」ボックスを選択または選択解除します。詳細については、「WebSphere InterChange Server システム・インプリメンテーション・ガイド」を参照してください。
特定の接続に対する トランザクション・プログラミング・モデルの指定

boolean 値を入力し、(この接続のみに対して) 目的のトランザクション・プログラミング・モデルを getDBConnection() メソッドのオプションの 2 番目の引き数として指定します。

次の getDBConnection() 呼び出しでは、ConnPool 接続プールから取得する接続に対して明示的なトランザクション・ブラケットを指定します。

conn = getDBConnection("ConnPool",
     false);
 

BaseCollaboration.implicitDBTransactionBracketing() メソッドを使用して、接続が使用する現在のトランザクション・プログラミング・モデルを決定できます。このメソッドは、トランザクション・プログラミング・モデルが暗黙的なトランザクション・ブラケットであるかどうかを示す boolean 値を戻します。

トランザクション・スコープの指定

接続のトランザクション・プログラミング・モデルにより、データベース・トランザクションのスコープの指定方法が決まります。このセクションの内容は次のとおりです。

暗黙的なトランザクション・ブラケットのあるトランザクション・スコープ

InterChange Server は、すべてのコラボレーションのトランザクション管理を処理します。コラボレーションのビジネス・オブジェクトのすべてのアクションは、1 単位として完了するか、または完了しません。このため、InterChange Server は、ビジネス・プロセス全体を単一の暗黙的なトランザクションとして処理します。なんらかの操作が失敗した場合は、「未解決のフロー」ブラウザーを使用して、失敗したコラボレーションの処理方法を選択します。

接続が暗黙的なトランザクション・ブラケットを使用する場合、InterChange Server は、接続プールの接続に関連付けられた、外部データベースで実行された操作のトランザクション管理も処理します。コラボレーションがデータベース操作を実行する場合、これらのデータベース操作はコラボレーションのビジネス・オブジェクトの一部です。InterChange Server は、メイン・トランザクションのサブトランザクション (コラボレーションのビジネス・プロセス) である暗黙的なトランザクションとしてこれらのデータベース操作を処理します。このデータベース・サブトランザクションは、コラボレーションが接続を取得すると同時に開始されます。

ICS は、コラボレーションの実行が完了すると、サブトランザクションを暗黙的に終了します。

このデータベース・サブトランザクションの成功または失敗は、以下のように、メイン・トランザクションの成功または失敗によって決まります。

コラボレーションが別のコラボレーションを直接呼び出す場合、最初のコラボレーションは親と呼ばれ、2 番目のコラボレーションは子と呼ばれます。親コラボレーションが子コラボレーションを呼び出す場合、InterChange Server は、子コラボレーションのトランザクションを別個に管理します。この子コラボレーションの成功または失敗は、親コラボレーションの成功または失敗とは関係ありません。子コラボレーションが失敗した場合、親コラボレーションはこの失敗の処理方法を決定できます。例えば、親コラボレーションも失敗する必要があると決定することも、その状態を修正または無視して実行を続行すると決定することもできます。

ただし、子コラボレーションの成功または失敗が親コラボレーションの成功または失敗と関係ないとしても、子が実行する暗黙的データベース・トランザクションについてはこのことが当てはまりません。暗黙的なトランザクション・ブラケットを使用するデータベース接続を介して子コラボレーションがデータベース操作を実行する場合、この子コラボレーションは親コラボレーションのトランザクションを継承します。

InterChange Server は、これらのデータベース操作を親コラボレーションのサブトランザクションとして処理します。つまり、以下のように、子コラボレーションの暗黙的データベース・サブトランザクションの最終トランザクション状態は、親 (またはトップレベル) コラボレーションの成功または失敗によって決まります。

InterChange Server は、親コラボレーションの成功または失敗が判別するまでは、サブトランザクションをコミットまたはロールバックしません。

この振る舞いにより、子コラボレーションが失敗し、親コラボレーションが実行の続行を選択した場合、InterChange Server は、子コラボレーションの暗黙的データベース・トランザクションをコミットします。

注:
InterChange Server は、子コラボレーションが実行し、まだアクティブであるデータベース・サブトランザクション (つまり、明示的なトランザクション・ブラケットを使用するデータベース接続を介して実行されているが、子のコラボレーション・テンプレートで明示的にコミットまたはロールバックされていないデータベース・トランザクション) を暗黙的データベース・サブトランザクションと同じように処理します。

子トランザクションを処理するこのメソッドにより、コラボレーションの開発者は、結合セマンティクスを明示的に使用せずに、子から親へのトランザクション結合を実行できます。また、子データベース・トランザクションが子レベルでコミットまたはロールバックされた場合、開発者は、子が (明示的または暗黙的に) 開始したトランザクションを、親が開始したグローバル・ビジネス・プロセス・トランザクションに関連付けることはできません。

注:
トランザクション・コラボレーションは、その親および子データベース・トランザクションに対してこれと同じモデルを使用します。

明示的なトランザクション・ブラケットのあるトランザクション・スコープ

接続が明示的なトランザクション・ブラケットを使用する場合、ICS は、コラボレーション・テンプレートが各データベース・トランザクションのスコープを明示的に指定することを必要とします。コラボレーションの成功または失敗とは関係ないデータベース操作を実行する必要がある場合、明示的なトランザクション・ブラケットが役に立ちます。例えば、特定の表がアクセスされたことを示す監査を実行する必要がある場合、この監査は、表へのアクセスが成功と失敗のいずれであるかとは関係なく実行する必要があります。明示的なトランザクションにデータベース操作の監査が含まれる場合、これらの操作はコラボレーションの成功または失敗とは関係なく実行されます。

表 59 に、明示的なトランザクションのトランザクション境界を管理するための CwDBConnection クラスのメソッドを示します。

表 59.
明示的にトランザクションを管理するための CwDBConnection メソッド
トランザクション管理操作 CwDBConnection メソッド
新しいトランザクションを開始します。 beginTransaction()
トランザクションの実行時にデータベースに対して行われたすべての変更をコミット (保管) し、トランザクションを終了します。 commit()
トランザクションが現在アクティブかどうかを確認します。 inTransaction()
トランザクションの実行時に行われたすべての変更をロールバック (バックアウト) し、トランザクションを終了します。 rollBack()

明示的なトランザクションのトランザクション・スコープを指定する手順は、以下のとおりです。

  1. beginTransaction() メソッドを呼び出して、トランザクションを開始します。
  2. beginTransaction() の呼び出しとトランザクションの終了との間の 単位として成功または失敗する必要があるすべての SQL を実行します。
  3. 以下のいずれかの方法により、トランザクションを終了します。

    トランザクションが失敗した原因となる条件を選択できます。失敗条件が満たされた場合は、条件をテストし、rollBack() を呼び出します。それ以外の場合は、commit() を呼び出してトランザクションを正常に終了します。

要確認:
beginTransaction() を使用して明示的なトランザクションの開始を指定しない 場合、データベースは、各 SQL ステートメントを個別トランザクションとして実行します。beginTransaction() を組み込んだが、接続が解放される前に commit() または rollback() を使用してデータベース・トランザクションの終了を指定しない 場合は、コラボレーションが成功したかどうかに基づき、InterChange Server Express によって暗黙的にトランザクションが終了されます。コラボレーションが成功の場合、ICS は、このデータベース・トランザクションをコミットします。コラボレーションが成功では ない 場合、ICS は、このデータベース・トランザクションを暗黙的にロールバックします。コラボレーションが成功かどうかにかかわらず、ICS は警告を記録します。

以下のコード・フラグメントは、CustDBConnPool の接続に関連付けられたデータベースの 3 つの表を更新します。これらの更新がすべて 成功した場合は、コード・フラグメントによって commit() メソッドでこれらの変更がコミットされます。トランザクション・エラーが発生した場合は、CwDBTransactionException 例外が生じ、コード・フラグメントによって rollback() メソッドが呼び出されます。

CwDBConnection connection = getDBConnection("CustDBConnPool", false);
  
 // Begin a transaction
 connection.beginTransaction();
  
 // Update several tables
 try
    {
    connection.executeSQL("update table1....");
    connection.executeSQL("update table2....");
    connection.executeSQL("update table3....");
  
    // Commit the transaction
    connection.commit();
    }
  
 catch (CwDBSQLException e)
    {
    // Roll back the transaction if an executeSQL() call throws
    // an exception
    connection.rollback();
    }
  
 // Release the database connection
 connection.release();
 

トランザクションが現在アクティブかどうかを判別するには、inTransaction() メソッドを使用します。

重要:
beginTransaction()commit()、および rollback() メソッドは、接続が明示的なトランザクション・ブラケットを使用する場合にのみ 使用します。接続が暗黙的なトランザクション・ブラケットを使用する場合は、これらのメソッドを使用すると、CwDBTransactionException 例外が発生します。

接続の解放

接続は、解放されると、その接続プールに戻され、ここでその他のコンポーネントが使用できるようになります。

データベースへの接続が解放される方法は、トランザクション・プログラミング・モデルによって決まります。このセクションの内容は次のとおりです。

暗黙的なトランザクション・ブラケットのある接続の解放

ICS は、データベース・トランザクションを終了すると、暗黙的なトランザクション・ブラケットを使用する接続を自動的に解放します。ICS は、コラボレーション・オブジェクトが成功または失敗のいずれかを確認するまでデータベース・トランザクションを終了しません。つまり、ICS は、コラボレーションが実行を終了するときにこれらの接続を解放します。コラボレーションが正常に実行されると、ICS は、アクティブなデータベース・トランザクションを自動的にコミットします。

コラボレーションの実行が失敗 (例えば、catch ステートメントによって処理されない例外がスローされる場合) すると、ICS は、アクティブなトランザクションを自動的にロールバックします。

明示的なトランザクション・ブラケットのある接続の解放

明示的なトランザクション・ブラケットを使用する接続の場合、接続は、以下のいずれかの状況で終了します。

CwDBConnection isActive() メソッドを使用すると、接続が解放されているかどうかを判別できます。

次のコード・フラグメントが示しているように、接続が解放されている場合は、isActive()false を戻します。

if (connection.isActive())
    connection.release();
 

重要:
トランザクションが現在アクティブである場合、release() メソッドは使用しないでください。暗黙的なトランザクション・ブラケットの場合、ICS は、コラボレーションが成功または失敗のいずれかを確認するまでデータベース・トランザクションを終了しません。このため、暗黙的なトランザクション・ブラケットを使用する接続にこのメソッドを使用すると、CwDBTransactionException 例外が発生します。

この例外を明示的に処理しないと、アクティブなトランザクションも自動的にロールバックされます。トランザクションがアクティブかどうかは、inTransaction() メソッドを使用して判別できます。ICS は、使用しているトランザクション・プログラミング・モデルとは関係なく、接続を自動的に解放します。多くの場合、接続は明示的に解放する必要はありません。

Copyright IBM Corp. 2004