FileDocCategorySizeDatePackage
TransactionManagerImpl.javaAPI DocGlassfish v2 API24468Fri May 04 22:36:40 BST 2007com.sun.jts.jta

TransactionManagerImpl

public class TransactionManagerImpl extends Object implements TransactionManager
An implementation of javax.transaction.TransactionManager using JTA. This is a singleton object
author
Tony Ng

Fields Summary
private static TransactionManagerImpl
tm
the singleton object
private org.omg.CosTransactions.Current
current
store the current psuedo object
private static HashMap
statusMap
mapping between CosTransaction status -> JTA status
private static int[]
directLookup
static final int
maxStatus
static Logger
_logger
private static int
xaTimeOut
store XAResource Timeout
private static org.omg.CosTransactions.Status[]
CosTransactionStatus
private static int[]
JTAStatus
Constructors Summary
private TransactionManagerImpl()
Create a transaction manager instance

        try {
            ORB orb = Configuration.getORB();
            current = org.omg.CosTransactions.CurrentHelper.
                narrow(orb.resolve_initial_references("TransactionCurrent"/*#Frozen*/));
            // transactionStates = new Hashtable();
        } catch (InvalidName inex) { 
			_logger.log(Level.SEVERE,
					"jts.unexpected_error_in_create_transaction_manager",inex);
        } catch (Exception ex) {
			_logger.log(Level.SEVERE,
					"jts.unexpected_error_in_create_transaction_manager",ex);
		}			
    
Methods Summary
private static voidassert_prejdk14(boolean value)
a simple assertion mechanism that print stack trace if assertion fails

        if (!value) {
            Exception e = new Exception();
			_logger.log(Level.WARNING,"jts.assert",e);
        }
    
public voidbegin()
Create a new transaction and associate it with the current thread.

exception
NotSupportedException Thrown if the thread is already associated with a transaction.


        try {
            // does not support nested transaction
            if (current.get_control() != null) {
                throw new NotSupportedException();
            }
            current.begin();
        } catch (TRANSACTION_ROLLEDBACK ex) {
            throw new NotSupportedException();
        } catch (SubtransactionsUnavailable ex) {
            throw new SystemException();
        }
    
public voidbegin(int timeout)
Create a new transaction with the given timeout and associate it with the current thread.

exception
NotSupportedException Thrown if the thread is already associated with a transaction.

        try {
            // does not support nested transaction
            if (current.get_control() != null) {
                throw new NotSupportedException();
            }
            ((com.sun.jts.CosTransactions.CurrentImpl)current).begin(timeout);
        } catch (TRANSACTION_ROLLEDBACK ex) {
            throw new NotSupportedException();
        } catch (SubtransactionsUnavailable ex) {
            throw new SystemException();
        }
    
public voidcommit()
Complete the transaction associated with the current thread. When this method completes, the thread becomes associated with no transaction.

exception
RollbackException Thrown to indicate that the transaction has been rolled back rather than committed.
exception
HeuristicMixedException Thrown to indicate that a heuristic decision was made and that some relevant updates have been committed while others have been rolled back.
exception
HeuristicRollbackException Thrown to indicate that a heuristic decision was made and that all relevant updates have been rolled back.
exception
SecurityException Thrown to indicate that the thread is not allowed to commit the transaction.
exception
IllegalStateException Thrown if the current thread is not associated with a transaction.


        try {
            current.commit(true);
        } catch (TRANSACTION_ROLLEDBACK ex) {
            throw new RollbackException();
        } catch (NoTransaction ex) {
            throw new IllegalStateException();
        } catch (NO_PERMISSION ex) {
            throw new SecurityException();
        } catch (HeuristicMixed ex) {
            throw new HeuristicMixedException();
        } catch (HeuristicHazard ex) {
            throw new HeuristicRollbackException();
        } catch (Exception ex) {
            throw new SystemException(ex.toString());
        }
        /***
        Transaction tran = getTransaction();
        if (tran == null) throw new IllegalStateException();
        tran.commit();
        ***/
    
private javax.transaction.TransactioncreateTransactionImpl(Control control)
TransactionState getOrCreateTransactionState(GlobalTID gtid, Transaction tran) throws SystemException { synchronized (transactionStates) { TransactionState result = (TransactionState) transactionStates.get(gtid); if (result == null) { result = new TransactionState(gtid); transactionStates.put(gtid, result); try { // remove Transaction State on transaction completion Synchronization sync = new SynchronizationListener(gtid, result); tran.registerSynchronization(sync); } catch (Exception ex) { _logger.log(Level.WARNING, "jts.unexpected_error_in_get_or_create_transaction_state",ex); throw new SystemException(); } } return result; } } TransactionState getTransactionState(GlobalTID gtid, Transaction tran) throws SystemException { synchronized (transactionStates) { return (TransactionState) transactionStates.get(gtid); } }

        GlobalTID gtid = null;
        if (Configuration.isLocalFactory()) {
            gtid = ((ControlImpl) control).getGlobalTID();
        } else {
            ControlImpl cntrlImpl = ControlImpl.servant(JControlHelper.narrow(control));
            gtid = cntrlImpl.getGlobalTID();
        }

        // return new TransactionImpl(this, control, gtid);
        return new TransactionImpl(control, gtid);
    
public intgetStatus()
Obtain the status of the transaction associated with the current thread.

return
The transaction status. If no transaction is associated with the current thread, this method returns the Status.NoTransaction value.

        try {
            Status status = current.get_status();
            return mapStatus(status);
        } catch (Exception ex) {
            throw new SystemException(ex.toString());
        }
    
public javax.transaction.TransactiongetTransaction()
Get the transaction object that represents the transaction context of the calling thread


        try {
            Control control = current.get_control();
            if (control == null) {
                return null;
            } else {
                return createTransactionImpl(control);
            }
        } catch (Unavailable uex) {
            throw new SystemException(uex.toString());
        } catch (Exception ex) {
            throw new SystemException(ex.toString());
        }
    
public static synchronized com.sun.jts.jta.TransactionManagerImplgetTransactionManagerImpl()
get the singleton TransactionManagerImpl


    // static block to initialize statusMap
     
        statusMap = new HashMap();
        int calcMaxStatus = 0;
        for (int i=0; i<CosTransactionStatus.length; i++) {
            statusMap.put(CosTransactionStatus[i],
                          new Integer(JTAStatus[i]));
            calcMaxStatus = Math.max(calcMaxStatus, CosTransactionStatus[i].value());
        }
        maxStatus = calcMaxStatus;
        directLookup = new int[maxStatus + 1];
        for (int i=0; i < directLookup.length; i++) {
            // initialize so that any unused slots point to 'unkown'.
            directLookup[i] = javax.transaction.Status.STATUS_UNKNOWN;
        }
        for (int i=0; i < CosTransactionStatus.length; i++) {
            int statusVal = CosTransactionStatus[i].value();
            if (statusVal < 0) {
                _logger.log(Level.SEVERE, "A negative CosTransaction Status value was detected.");
            } else {
                directLookup[statusVal] = JTAStatus[i];
            }
        }

    
        if (tm == null) {
            tm = new TransactionManagerImpl();
        }
        return tm;
    
public static intgetXAResourceTimeOut()

		return xaTimeOut;
	
public static javax.resource.spi.XATerminatorgetXATerminator()
Provides a handle to a XATerminator instance. The XATerminator instance could be used by a resource adapter to flow-in transaction completion and crash recovery calls from an EIS.

return
a XATerminator instance.

        return new XATerminatorImpl();
    
public static voidinitJTSProperties(java.util.Properties props, java.lang.String logDir, boolean trace, java.lang.String traceDir)
extends props with the JTS-related properties based on the specified parameters. The properties will be used as part of ORB.init() call.

param
prop the properties that will be extended
param
logDir directory for the log, current directory if null
param
trace enable JTS tracing
param
traceDir directory for tracing, current directory if null

        if (traceDir == null) traceDir = "."/*#Frozen*/;
        if (logDir == null) logDir = "."/*#Frozen*/;

        props.put("com.sun.corba.se.CosTransactions.ORBJTSClass"/*#Frozen*/,
                  "com.sun.jts.CosTransactions.DefaultTransactionService"/*#Frozen*/);
        props.put("com.sun.jts.traceDirectory"/*#Frozen*/, traceDir);
        props.put("com.sun.jts.logDirectory"/*#Frozen*/, logDir);
        if (trace) {
            props.put("com.sun.jts.trace"/*#Frozen*/, "true"/*#Frozen*/);
        }
    
public static intmapStatus(org.omg.CosTransactions.Status status)
given a CosTransactions Status, return the equivalent JTA Status

        int statusVal = status.value();
        if (statusVal < 0 || statusVal > maxStatus) {
            return javax.transaction.Status.STATUS_UNKNOWN;
        } else {
            return directLookup[statusVal];
        }
    
public static voidrecover(java.util.Enumeration xaResourceList)
The application server passes in the list of XAResource objects to be recovered.

param
xaResourceList list of XAResource objects.

        RecoveryManager.recoverXAResources(xaResourceList);
    
public static voidrecreate(javax.transaction.xa.Xid xid, long timeout)
Recreate a transaction based on the Xid. This call causes the calling thread to be associated with the specified transaction.

param
xid the Xid object representing a transaction.
param
timeout positive, non-zero value for transaction timeout.

                
        // check if xid is valid
        if (xid == null || xid.getFormatId() == 0 ||
                xid.getBranchQualifier() == null || 
                xid.getGlobalTransactionId() == null) {
            WorkException workExc = new WorkCompletedException("Invalid Xid");
            workExc.setErrorCode(WorkException.TX_RECREATE_FAILED);
            throw workExc;
        }

        // has TransactionService been initialized?
        if (!DefaultTransactionService.isActive()) {
            WorkException workExc = 
                new WorkCompletedException("Transaction Manager unavailable");
            workExc.setErrorCode(WorkException.TX_RECREATE_FAILED);
            throw workExc;
        }
        
        // recreate the transaction        
        GlobalTID tid = new GlobalTID(xid);
        try {        
            CurrentTransaction.recreate(
		tid, (int) ((timeout <= 0) ? 0 : timeout));
        } catch (Throwable exc) {
            String errorCode = WorkException.TX_RECREATE_FAILED;
            if (exc instanceof INVALID_TRANSACTION &&
                    (((INVALID_TRANSACTION) exc).minor == 
                        MinorCode.TX_CONCURRENT_WORK_DISALLOWED)) {
                errorCode = WorkException.TX_CONCURRENT_WORK_DISALLOWED;
            }
            WorkException workExc = new WorkCompletedException(exc);
            workExc.setErrorCode(errorCode);
            throw workExc;             
        }  
    
public static voidrelease(javax.transaction.xa.Xid xid)
Release a transaction. This call causes the calling thread to be dissociated from the specified transaction.

param
xid the Xid object representing a transaction.

                
        GlobalTID tid = new GlobalTID(xid);
        try {        
            CurrentTransaction.release(tid);
        } catch (Throwable exc) {
            String errorCode = WorkException.UNDEFINED;
            if (exc instanceof INTERNAL) {
                errorCode = WorkException.INTERNAL;
            }
            WorkException workExc = new WorkCompletedException(exc);
            workExc.setErrorCode(errorCode);            
            throw workExc;             
        }
    
public voidresume(javax.transaction.Transaction suspended)
Resume the transaction context association of the calling thread with the transaction represented by the supplied Transaction object. When this method returns, the calling thread is associated with the transaction context specified.

        // thread is already associated with a transaction?
        if (getTransaction() != null) throw new IllegalStateException();
        // check for invalid Transaction object
        if (suspended == null) throw new InvalidTransactionException();
        if ((suspended instanceof TransactionImpl) == false) {
            throw new InvalidTransactionException();
        }
        Control control = ((TransactionImpl) suspended).getControl();
        try {
            current.resume(control);
        } catch (InvalidControl ex) {
			//_logger.log(Level.FINE,"Invalid Control Exception in resume",ex);
            throw new InvalidTransactionException();
        } catch (Exception ex) {
            throw new SystemException(ex.toString());
        }
    
public voidrollback()
Roll back the transaction associated with the current thread. When this method completes, the thread becomes associated with no transaction.

exception
SecurityException Thrown to indicate that the thread is not allowed to roll back the transaction.
exception
IllegalStateException Thrown if the current thread is not associated with a transaction.


        try {
            current.rollback();
        } catch (NoTransaction ex) {
            throw new IllegalStateException();
        } catch (NO_PERMISSION ex) {
            throw new SecurityException();
        } catch (Exception ex) {
            throw new SystemException(ex.toString());
        }

        /***
        Transaction tran = getTransaction();
        if (tran == null) throw new IllegalStateException();
        tran.rollback();
        ***/
    
public voidsetRollbackOnly()
Modify the transaction associated with the current thread such that the only possible outcome of the transaction is to roll back the transaction.

exception
IllegalStateException Thrown if the current thread is not associated with a transaction.


        try {
            current.rollback_only();
        } catch (NoTransaction ex) {
            throw new IllegalStateException();
        } catch (Exception ex) {
            throw new SystemException(ex.toString());
        }
    
public synchronized voidsetTransactionTimeout(int seconds)
Modify the timeout value that is associated with transactions started by subsequent invocations of the begin method.

If an application has not called this method, the transaction service uses some default value for the transaction timeout.

param
seconds The value of the timeout in seconds. If the value is zero, the transaction service restores the default value. If the value is negative a SystemException is thrown.
exception
SystemException Thrown if the transaction manager encounters an unexpected error condition.


        try {
            if (seconds < 0) {
				String msg = LogFormatter.getLocalizedMessage(_logger,
							 "jts.invalid_timeout");
                throw new SystemException(msg);
            }
            current.set_timeout(seconds);
        } catch (Exception ex) {
            throw new SystemException(ex.toString());
        }
    
public static voidsetXAResourceTimeOut(int value)
used to set XAResource timeout

		xaTimeOut = value;
	
public javax.transaction.Transactionsuspend()
Suspend the transaction currently associated with the calling thread and return a Transaction object that represents the transaction context being suspended. If the calling thread is not associated with a transaction, the method returns a null object reference. When this method returns, the calling thread is associated with no transaction.

        try {
            Control control = current.suspend();
            if (control == null) return null;
            return createTransactionImpl(control);
        } catch (Unavailable uex) {
            throw new SystemException(uex.toString());
        } catch (Exception ex) {
            throw new SystemException(ex.toString());
        }