JDBCを使ったデータベース接続のトランザクションをApcoordinatorに制御させるには、ビジネスクラスのpreprocessメソッドまたはbeforeTransactionBeginメソッドで以下の処理を実行します。
com.fujitsu.uji.DispatchContextクラスのgetUjiTransactionメソッドを使ってcom.fujitsu.uji.transaction.UjiTransactionオブジェクトを取得します。UjiTransactionはトランザクション管理機能においてトランザクションを管理するクラスです。
UjiTransactionのsetSQLConnectionメソッドを使い、UjiTransactionにjava.sql.Connectionオブジェクトを登録します。
UjiTransactionにjava.sql.Connectionオブジェクトを登録した場合、Apcoordinatorはjava.sql.Connectionインターフェイスを使ってトランザクションを制御します。UserTransactionインターフェイスを使ったトランザクション管理は無効になります。
以下はビジネスクラスの記述例です。
import java.util.Hashtable; import java.sql.Connection; import javax.sql.DataSource; import java.sql.SQLException; import javax.naming.InitialContext; import javax.naming.Context; import javax.naming.NamingException; import com.fujitsu.uji.transaction.GenericTransactionHandler; import com.fujitsu.uji.transaction.UjiTransaction; import com.fujitsu.uji.DispatchContext; import com.fujitsu.uji.Preprocessor; public class SampleHandler extends GenericTransactionHandler { Connection connection = null; public int preprocess(DispatchContext context) { try { Hashtable hashtable = new Hashtable(); hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "com.fujitsu.symfoware.jdbc2.jndisp.SYMContextFactory"); hashtable.put(Context.PROVIDER_URL, "SYM://SYMFOSV"); InitialContext ctx = new InitialContext(hashtable); DataSource source = (DataSource)ctx.lookup("jdbc/sampledb"); connection = source.getConnection("userName", "password"); // (1) UjiTransaction ujiTransaction = context.getUjiTransaction(); ujiTransaction.setSQLConnection(connection); // (2) // connection.setAutoCommit(false)はUjiTransactionによって実行される // ため、アプリケーションプログラムで実行する必要はありません。 } catch (SQLException e) { ... } catch (NamingException e) { ... } return Preprocessor.EVAL; } ... public Object postprocess(DispatchContext context, Object result) { closeConnection(); return result; } public Object handleException(DispatchContext context, Throwable th) { closeConnection(); return null; } private void closeConnection() { if (connection != null) { try { connection.close(); } catch (SQLException e) { ... } } } }
preprocessメソッド内の(1)でデータベース接続を確立し、(2)でUjiTransactionオブジェクトに登録しています。これにより、(1)で作成したデータベース接続のトランザクションがApcoordinatorによって管理されます。データベース接続の切断はアプリケーションで処理する必要があります。この記述例では、postprocessメソッド、handleExceptionメソッドでデータベース接続を切断しています。
ポイント
上記の記述例の処理をビジネスクラス再試行機能と併用した場合、再試行時はデータベース接続が新規に作成されず、既存のデータベース接続が再利用されます。preprocess, postprocess, handleExceptionメソッドは再試行の範囲に含まれないためです。 再試行のたびにデータベース接続の作成と切断を実行したい場合は、beforeTransactionBeginメソッドでデータベース接続の確立とUjiTransactionオブジェクトへの登録を、afterTransactionCompletionメソッドで切断を実行します。
JDBC以外のインターフェイスでも、アダプタを作成することによって、Apcoordinatorにトランザクションを制御させることができます。この場合、以下のようにプログラムを作成します。
Apcoordinatorがトランザクションを制御できるようにするためのアダプタを作成します。アダプタは、com.fujitsu.uji.transaction.Resourceインターフェイスを実装します。Resourceインターフェイスのbegin, commit, rollbackメソッドが呼び出されたときに、トランザクションの開始、コミット、ロールバックが実行されるようにアダプタを作成します。
ビジネスクラスのbeforeTransactionBeginメソッドで、トランザクションを制御する対象をアダプタでラップし、UjiTransactionクラスのsetResourceメソッドによりアダプタをUjiTransactionに登録します。
UjiTransactionのsetResourceメソッドを使用した場合、Apcoordinatorは登録されたアダプタを使用してトランザクションを制御します。UserTransactionインターフェイスを使ったトランザクション管理は無効になります。