Home   Single Page

トランザクションとorg.zkoss.zk.util.Initiator

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トランザクションとイニシエーター

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