Distributed transaction のような複雑なアプリケーションには、トランザクションのライフサイクルをはっきりとコントロールしなければなりません。すべてのデータベースアクセスが イベントリスナの中で処理される場合、そのままでZKにても使用できます。J2EE/Web サーバーのドキュメントに薦められた方法で、トランザクションを開始、コミット、ロールバックします。
一方、ZUMLページ(コンポーネント作成段階)が同じトランザクションの中で処理されるには、上のセクションの中で説明したように、org.zkoss.zk.util.Initiatorインターフェースを実装して、与えられたページのライフサイクルをコントロールします。
概略の実装は以下のように示されます。
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.util.Initiator;
public class TransInitiator implements Initiator {
private boolean _err;public void doInit(Page page, Object[] args) {
startTrans(); //depending the container, see below
}
public void doCatch(Throwable ex) {
_err = true;
rollbackTrans(); //depending the container, see below
}public void doFinally() {
if (!_err)
commitTrans(); //depending the container, see below
}
}
説明したように、トランザクションは doInit メソッドで開始して、org.zkoss.zk.util.Inittiator インターフェースで終了します。
トランザクションを開始、コミット、ロールバックする方法は、使用しているコンテナーによって変わります。
J2EEコンテナーを使用する場合、トランザクションマネージャー (javax.transaction.TransactionManager) を検索し、begin メソッドを呼び出してトランザクションを開始します。
ロールバックするには rollback メソッドを呼び出します。コミットには commit メソッドを呼び出します。
トランザクションマネージャーなしのウェブコンテナーを使用している場合、データベースコネクションを構築することでトランザクションを開始します。
そして、状況に応じて、commit と rollback メソッドを呼び出します。
import java.sql.*; import javax.sql.DataSource;
import javax.naming.InitContext;
import org.zkoss.util.logging.Log;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.util.Initiator;
public class TransInitiator implements Initiator {
private static final Log log = Log.lookup(TransInitiator.class);
private Connection _conn;
private boolean _err;
public void doInit(Page page, Object[] args) {
try {
DataSource ds = (DataSource)new InitialContext()
.lookup("java:comp/env/jdbc/MyDB");
_conn = ds.getConnection();
} catch (Throwable ex) {
throw UiException.Aide.wrap(ex);
}
}
public void doCatch(Throwable t) {
if (_conn != null) {
try {
_err = true;
_conn.rollback();
} catch (SQLException ex) {
log.warning("Unable to roll back", ex);
}
}
}
public void doFinally() {
if (_conn != null) {
try {
if (!_err)
_conn.commit();
} catch (SQLException ex) {
log.warning("Failed to commit", ex);
} finally {
try {
_conn.close();
} catch (SQLException ex) {
log.warning("Unable to close transaction", ex);
}
}
}
}
}