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); } } } } }