FileDocCategorySizeDatePackage
ContainerSynchronization.javaAPI DocGlassfish v2 API8786Wed May 30 11:30:54 BST 2007com.sun.ejb.containers

ContainerSynchronization

public final class ContainerSynchronization extends Object implements Synchronization
This class intercepts Synchronization notifications from the TransactionManager and forwards them to the appropriate container. There is one ContainerSynchronization instance per tx. All bean instances (of all types) participating in the tx must be added by the container to the ContainerSynchronization, so that the beans can be called during before/afterCompletion. This class also provides special methods for PersistenceManager Sync and Timer objects which must be called AFTER the containers during before/afterCompletion.

Fields Summary
private static final Logger
_logger
private ArrayList
beans
private Vector
pmSyncs
private Hashtable
timerSyncs
private Transaction
tx
private ContainerFactoryImpl
containerFactory
private SFSBTxCheckpointCoordinator
sfsbTxCoordinator
Constructors Summary
ContainerSynchronization(Transaction tx, ContainerFactoryImpl containerFactory)


    // Note: this must be called only after a Tx is begun.
      
			      
    
        this.tx = tx;
        this.containerFactory = containerFactory;
    
Methods Summary
voidaddBean(EJBContextImpl bean)

        beans.add(bean);
    
voidaddPMSynchronization(javax.transaction.Synchronization sync)

        pmSyncs.add(sync);
    
voidaddTimerSynchronization(TimerPrimaryKey timerId, javax.transaction.Synchronization sync)

        timerSyncs.put(timerId, sync);
    
public voidafterCompletion(int status)

	
        for ( int i=0; i<pmSyncs.size(); i++ ) {
            Synchronization sync = (Synchronization)pmSyncs.elementAt(i);
            try {
                sync.afterCompletion(status);
            } catch ( Exception ex ) {
                _logger.log(Level.SEVERE, "ejb.after_completion_error", ex);
            }
        }

        // call afterCompletion for each bean instance
        for ( int i=0; i<beans.size();i++  ) {
            EJBContextImpl context = (EJBContextImpl)beans.get(i);
            BaseContainer container = (BaseContainer)context.getContainer();
            try {
                if( container != null ) {
                    container.afterCompletion(context, status);
                } else {
                    // Might be null if bean was removed.  Just skip it.
                    _logger.log(Level.FINE, "context with empty container in "
                                +
                                " ContainerSynchronization.afterCompletion");
                }
            } catch ( Exception ex ) {
                _logger.log(Level.SEVERE, "ejb.after_completion_error", ex);
            }
        }

	if (sfsbTxCoordinator != null) {
	    sfsbTxCoordinator.doTxCheckpoint();
	}

        for ( Iterator iter = timerSyncs.values().iterator(); 
              iter.hasNext(); ) {
            Synchronization timerSync = (Synchronization) iter.next();
            try {
                timerSync.afterCompletion(status);
            } catch ( Exception ex ) { 
                _logger.log(Level.SEVERE, "ejb.after_completion_error", ex);
            }
        }

        // tell ContainerFactory to remove this tx/sync from its table
        containerFactory.removeContainerSync(tx);
    
public voidbeforeCompletion()

        // first call beforeCompletion for each bean instance
        for ( int i=0; i<beans.size(); i++ ) {
            EJBContextImpl context = (EJBContextImpl)beans.get(i);
            BaseContainer container = (BaseContainer)context.getContainer();
            try {
                if( container != null ) {
		    if (container.isUndeployed()) {
			_logger.log(Level.WARNING, "Marking Tx for rollback "
			    + " because container for " + container
			    + " is undeployed");
			try {
			    tx.setRollbackOnly();
			} catch (SystemException sysEx) {
			    _logger.log(Level.FINE, "Error while trying to "
				+ "mark for rollback", sysEx);
			}
		    } else {
			container.beforeCompletion(context);
		    }
                } else {
                    // Might be null if bean was removed.  Just skip it.
                    _logger.log(Level.FINE, "context with empty container in " +
                                " ContainerSynchronization.beforeCompletion");
                }
            } catch ( Exception ex ) {
                // rollback the Tx. The client will get
                // a EJB/RemoteException or a TransactionRolledbackException.
                _logger.log(Level.SEVERE,"ejb.remote_or_txnrollback_exception",ex);
                try {
                    tx.setRollbackOnly();
                } catch ( SystemException e ) {
                    _logger.log(Level.FINE, "", ex);
                }
                return; // no need to call remaining beforeCompletions
            }
        }

        // now call beforeCompletion for all pmSyncs
        for ( int i=0; i<pmSyncs.size(); i++ ) {
            Synchronization sync = (Synchronization)pmSyncs.elementAt(i);
            try {
                sync.beforeCompletion();
            } catch ( Exception ex ) {
                // rollback the Tx. The client will get
                // a EJB/RemoteException or a TransactionRolledbackException.
                _logger.log(Level.SEVERE,"ejb.remote_or_txnrollback_exception",ex);
                try {
                    tx.setRollbackOnly();
                } catch ( SystemException e ) {
                    _logger.log(Level.FINE, "", ex);
                }
                return; // no need to call remaining beforeCompletions
            }
        }
    
java.util.VectorgetBeanList()

        Vector vec = new Vector();
        for (Iterator iter = beans.iterator(); iter.hasNext(); ) {
            vec.add(iter.next());
        }
        return vec;
    
javax.transaction.SynchronizationgetTimerSynchronization(TimerPrimaryKey timerId)

        return (Synchronization) timerSyncs.get(timerId);
    
voidregisterForTxCheckpoint(SessionContextImpl sessionCtx)

	//No need to synchronize
	if (sfsbTxCoordinator == null) {
	    sfsbTxCoordinator = new SFSBTxCheckpointCoordinator();
	}

	sfsbTxCoordinator.registerContext(sessionCtx);
    
voidremoveBean(EJBContextImpl bean)

        beans.remove(bean);
    
voidremoveTimerSynchronization(TimerPrimaryKey timerId)

        timerSyncs.remove(timerId);