Transaction and org.zkoss.zk.util.Initiator

For sophisticated application (such as distributed transaction), you might have to control the lifecyle of a transaction explicitly. If all database access is done in event listeners, there is nothing to change to make it work under ZK. You start, commit or rollback a transaction the same way as suggested in the document of your J2EE/Web server.

However, if you want the evaluation of the whole ZUML page (the Component Creation Phases) is done in the same transaction, then you, as described in the above section, could implement the org.zkoss.zk.util.Initiator interface to control the transaction lifecycle for a given page.

The skeletal implementation is illustrated as follows.

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

As depicted, the transaction starts in the doInit method, and ends in the doFinally method of the org.zkoss.zk.util.Initiator interface.

How to start, commit and rollback an transaction depends on the container you use.

J2EE Transaction and Initiator

If you are using a J2EE container, you could look up the transaction manager (javax.transaction.TransactionManager), and then invoke its begin method to start an transaction. To rollback, invoke its rollback method. To commit, invoke its commit method.

Web Containers and Initiator

If you are using a Web container without transaction managers, you could start a transaction by constructing a database connection. Then, invoke its commit and rollback methods accordingly.

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