Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    * 
    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    * 
    * The contents of this file are subject to the terms of either the GNU
    * General Public License Version 2 only ("GPL") or the Common Development
    * and Distribution License("CDDL") (collectively, the "License").  You
    * may not use this file except in compliance with the License. You can obtain
   * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   * language governing permissions and limitations under the License.
   * 
   * When distributing the software, include this License Header Notice in each
   * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   * Sun designates this particular file as subject to the "Classpath" exception
   * as provided by Sun in the GPL Version 2 section of the License file that
   * accompanied this code.  If applicable, add the following below the License
   * Header, with the fields enclosed by brackets [] replaced by your own
   * identifying information: "Portions Copyrighted [year]
   * [name of copyright owner]"
   * 
   * Contributor(s):
   * 
   * If you wish your version of this file to be governed by only the CDDL or
   * only the GPL Version 2, indicate your decision by adding "[Contributor]
   * elects to include this software in this distribution under the [CDDL or GPL
   * Version 2] license."  If you don't indicate a single choice of license, a
   * recipient has the option to distribute your version of this file under
   * either the CDDL, the GPL Version 2 or to extend the choice of license to
   * its licensees as provided above.  However, if you add GPL Version 2 code
   * and therefore, elected the GPL Version 2 license, then the option applies
   * only if the new code is made subject to such option by the copyright
   * holder.
   */
  
  /*
   * Copyright 2004-2005 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  
  //----------------------------------------------------------------------------
  //
  // Module:      TopCoordinator.java
  //
  // Description: Top-level transaction Coordinator object implementation.
  //
  // Product:     com.sun.jts.CosTransactions
  //
  // Author:      Simon Holdsworth
  //
  // Date:        March, 1997
  //
  // Copyright (c):   1995-1997 IBM Corp.
  //
  //   The source code for this program is not published or otherwise divested
  //   of its trade secrets, irrespective of what has been deposited with the
  //   U.S. Copyright Office.
  //
  //   This software contains confidential and proprietary information of
  //   IBM Corp.
  //----------------------------------------------------------------------------
  
  package com.sun.jts.CosTransactions;
  
  import java.util.*;
  
  import org.omg.CORBA.*;
  import  org.omg.CosTransactions.*;
  
  //import com.sun.jts.codegen.otsidl.JCoordinatorHelper;
  //import com.sun.jts.codegen.otsidl.JCoordinatorOperations;
  //import java.io.PrintStream;
  //import java.util.Vector;
  
  //import com.sun.enterprise.transaction.OTSResourceImpl;
  //import com.sun.enterprise.transaction.SynchronizationImpl;
  
  import  com.sun.jts.trace.*;
  
The TopCoordinator interface is our implementation of the standard Coordinator interface that is used for top-level transactions. It allows Resources to be registered for participation in a top-level transaction. In addition the TopCoordinator recovery interface can be used if the connection to a superior Coordinator is lost after a transaction is prepared. As an instance of this class may be accessed from multiple threads within a process, serialisation for thread-safety is necessary in the implementation. The information managed should be reconstructible in the case of a failure.

Author(s):
Simon Holdsworth, IBM Corporation
Version:
0.02
See also:
 
 
 //----------------------------------------------------------------------------
 // CHANGE HISTORY
 //
 // Version By     Change Description
 //   0.01  SAJH   Initial implementation.
 //   0.02  GDH    Gordon Hutchison April 1998
 //                Some improvements to the way the additional tran states in
 //                OTS 1.1 (vs 1.0) are handled and also improvements to logic
 //                used in recovery.
 //   0.03  GDH    Gordon 27th Jan 1999
 //                Changes marked by COPDEF1 to fix two defects in COP work.
 //   0.04  GDH    Gordon 28th Jan 1999
 //                Change marked by COPDEF2, in COP if resource voted rb
 //                our code set state to COB_RB twice which is invalid:
 //                first state change removed as unnecessary.
 //-----------------------------------------------------------------------------
 
 public class TopCoordinator extends CoordinatorImpl {
     String              name = null;
     RegisteredSyncs     synchronizations = null;
     SuperiorInfo        superInfo = null;
     NestingInfo         nestingInfo = null;
     TransactionState    tranState = null;
     CoordinatorLog      logRecord = null;
     CompletionHandler   terminator = null;
     boolean             registered = false;
     boolean             registeredSync = false;
     boolean             root = true;
     boolean             rollbackOnly = false;
     boolean             dying = false;
     boolean             temporary = false;
     int                 hash = 0;
 
 	/*
 		Logger to log transaction messages
 	*/ 
     // added (Ram J) for memory Leak fix.
     Vector recoveryCoordinatorList = null;
 
    // added (sankar) for delegated recovery support
    boolean delegated = false;
    String logPath = null;

    
Default TopCoordinator constructor.

Parameters:
Returns:
See also:
 
     TopCoordinator() {
         // No persistent reference is created in this case.
     }

    
Creates and initialises a new root TopCoordinator, and returns the global identifier for the transaction. The timeout value, if non-zero, is used to establish a time-out for the transaction. A CoordinatorLog object is created at this time if the log is available.

Parameters:
timeOut The time-out value for the transaction.
Returns:
Throws:
LogicErrorException An internal logic error occurred.
See also:
 
     TopCoordinator(int timeOutthrows LogicErrorException {
 
         // If this execution of the process is recoverable, then create a
         // CoordinatorLog object for the top-level transaction. Each of the
         // implementation classes that use the CoordinatorLog have been written
         // to be able to work with or without a CoordinatorLog reference.
 
         if (Configuration.isRecoverable()) {
 	    // get a CoordinatorLog object from the cache
 	    // instead of instantiating a new one    Arun 9/27/99
 	     = CoordinatorLogPool.getCoordinatorLog();
         } else {
              = null;
         }
 
         // Allocate a new global identifier for the transaction.
 
          = new TransactionState();
 
         // Store information about the superior, ancestors and
         // participants of the new transaction.
 
                                      null);
 
         // Cache the name  - create a buffer and print the global XID into it.
 
         // name = superInfo.globalTID.toString();
 
         // Cache the hash value of the Coordinator.
 
          = ..hashCode();
 
         // Zero out the RegisteredResources, NestingInfo and RegisteredSyncs
         // references. These will be created when they are required.
 
          = null;
          = null;
          = null;
 
         // Set other instance variables.
 
          = true;
          = true;
          = true;
          = false;
          = false;
          = false;
          = null;
 
         if (!.setState(.)) {
 
             // Set the state of the transaction to active before making
             // it visible to the TransactionManager.
 
             LogicErrorException exc =
                 new LogicErrorException(
 					"jts.invalid_state_change"));
             throw exc;
 
         } else {
 
             // Inform the RecoveryManager of the existence of this transaction.
             if (!RecoveryManager.addCoordinator(.,
                                                 .,
                                                 this,
                                                 timeOut)) {
                 LogicErrorException exc =
                     new LogicErrorException(
 						"jts.transaction_id_already_in_use"));
                 throw exc;
             }
         }
     }

    
Creates and initialises a subordinate TopCoordinator, given the global identifier and superior Coordinator reference, and returns the local identifier for the transaction. The timeout value, if non-zero, is used to establish a time-out for the subordinate transaction. The temporary flag indicates whether the TopCoordinator was created as a temporary ancestor.

Parameters:
timeOut The timeout value for the transaction.
globalTID The global identifier for the transaction.
superior The superior Coordinator.
temporary The temporary indicator.
Returns:
Throws:
LogicErrorException An internal logic error occurred.
See also:
 
     TopCoordinator(int timeOutGlobalTID globalTID, Coordinator superior,
             boolean temporarythrows LogicErrorException {
 
         // If this execution of the process is recoverable, then create a
         // CoordinatorLog object for the top-level transaction. Each of the
         // implementation classes that use the CoordinatorLog have been written
         // to be able to work with or without a CoordinatorLog reference.
 
         if (Configuration.isRecoverable()) {
 	    // get a CoordinatorLog object from the cache
 	    // instead of instantiating a new one    Arun 9/27/99
 	     = CoordinatorLogPool.getCoordinatorLog();
         } else {
              = null;
         }
 
         // Allocate a new local identifier for the transaction.
         // If one cannot be allocated, raise an exception as the
         // transaction cannot be started.
 
          = new TransactionState(globalTID,);
 
         // Store information about the superior, ancestors and participants
         // of the new subordinate transaction.
 
                                      superior);
 
         // Cache the name  - create a buffer and print the global XID into it.
 
         // name = superInfo.globalTID.toString();
 
         // Cache the hash value of the Coordinator.
 
          = ..hashCode();
 
         // Zero out the RegisteredResources, NestingInfo and RegisteredSyncs
         // references. These will be created when they are required.
 
          = null;
          = null;
          = null;
 
         // Set other instance variables.
 
          = false;
          = false;
          = false;
          = false;
          = false;
         this. = temporary;
          = null;
 
         // Set the state of the transaction to active before making it
         // visible to the RecoveryManager.
 
         if (!.setState(.)) {
             LogicErrorException exc =
                 new LogicErrorException(
 					"jts.invalid_state_change"));
             throw exc;
         } else {
             if (!RecoveryManager.addCoordinator(globalTID.,
                                                 thistimeOut)) {
                 LogicErrorException exc =
                     new LogicErrorException(
 						"jts.transaction_id_already_in_use"));
                 throw exc;
             }
         }
     }

    
Cleans up the objects state.

Parameters:
Returns:
See also:
 
     synchronized public void doFinalize() {
 
         // Set the flag to indicate that the coordinator is being destroyed.
 
          = true;
 
         // What we do when destroyed depends on the transaction's state.
         // We assume that temporary Coordinators have rolled bak at this point.
 
         int state = .;
         if ( != null && !) {
             state = .;
         }
 
         switch (state) {
 
         // If the transaction is active it should be rolled back.  This
         // will result in the TopCoordinator self-destructing at the
         // end of two-phase commit.
 
         case . :
             try {
                 rollback(true);
             } catch (Throwable exc) {}
 
             break;
 
         // For committed or rolled-back, we really need to destroy the
         // object. Also for prepared_readonly.
 
         case . :
         case . :
         case . :
 
 	    /*
             if (tranState != null) {
                 tranState.finalize();
             }
 	    */
 
             if ( != null) {
                 .doFinalize();
             }
 
 	    /*
             if (nestingInfo != null) {
                 nestingInfo.doFinalize();
             }
 
             if (participants != null) {
                 participants.finalize();
             }
 
             if (synchronizations != null) {
                 synchronizations.finalize();
             }
 	    */
 
              = null;
              = null;
              = null;
              = null;
              = null;
              = null;
              = null;
              = null;
             break;
 
         // For any other state, the transaction is completing, so the
         // TopCoordinator will eventually self-destruct.  We do nothing here.
 
         default :
             break;
         }
     }

    
Directs the TopCoordinator to recover its state after a failure, based on the given CoordinatorLog object. If the TopCoordinator has already been defined or recovered, the operation returns immediately. Otherwise the TopCoordinator restores the state of its internal objects using their recovery operations, which in turn recover their state from the CoordinatorLog object.

Parameters:
log The CoordinatorLog object which contains the Coordinators state.
Returns:
See also:
 
     synchronized void reconstruct(CoordinatorLog log) {
 
         // Set up instance variables.
 
          = false;
          = false;
          = false;
          = false;
          = false;
          = false;
          = null;
          = log;
          = null;
 
         // Zero out NestingInfo and Synchronizations references. These won't be
         // needed for a recovered transaction.
 
          = null;
          = null;
 
         // Use the result of the TransactionState reconstruction to
         // decide whether to continue with recovery of this transaction.
 
          = new TransactionState();
         int state = .reconstruct(log);
         if (state == . ||
                 state == . ||
                 // state == TransactionState.STATE_COMMITTED_ONE_PHASE_OK ||
                 // state == TransactionState.STATE_COMMIT_ONE_PHASE_ROLLED_BACK ||
                 state == .) {
 
             // If the transaction is discarded, then ensure that
             // the log record is discarded.
 
             CoordinatorLog.removeLog(log.localTID);
             destroy();
 
         } else {
 
             // Otherwise continue with reconstruction.
              = new RegisteredResources(this);
             .reconstruct(log);
 
             // Reconstruct the SuperiorInfo object.  This will result in a
             // call to RecoveryManager.addCoordinator (which is done
             // because reconstruction of the object references in the
             // SuperiorInfo requires the Coordinator to
             // already be known to the RecoveryManager).
 
              = new SuperiorInfo();
             .reconstruct(logthis);
 
             // Cache the name  - create a buffer and print the
             // global XID into it.
 
              = ..toString();
 
             // Cache the hash value of the Coordinator.
 
              = ..hashCode();
         }
     }

    
Directs the TopCoordinator to recover its state after a failure, based on the given CoordinatorLog object for the given logpath. If the TopCoordinator has already been defined or recovered, the operation returns immediately. Otherwise the TopCoordinator restores the state of its internal objects using their recovery operations, which in turn recover their state from the CoordinatorLog object.

Parameters:
log The CoordinatorLog object which contains the Coordinators state.
logPath Location of the log file
Returns:
See also:
 
     synchronized void delegated_reconstruct(CoordinatorLog logString logPath ) {
 
         // Set up instance variables.
 
          = false;
          = false;
          = false;
          = false;
          = false;
          = false;
          = null;
          = log;
          = null;
 
         // Zero out NestingInfo and Synchronizations references. These won't be
         // needed for a recovered transaction.
 
          = null;
          = null;
 
          = true;
         this. = logPath;
 
         // Use the result of the TransactionState reconstruction to
         // decide whether to continue with recovery of this transaction.
 
          = new TransactionState();
         // int state = tranState.delegated_reconstruct(log);
         int state = .reconstruct(log);
         if (state == . ||
                 state == . ||
                 // state == TransactionState.STATE_COMMITTED_ONE_PHASE_OK ||
                 // state == TransactionState.STATE_COMMIT_ONE_PHASE_ROLLED_BACK ||
                 state == .) {
 
             // If the transaction is discarded, then ensure that
             // the log record is discarded.
 
             CoordinatorLog.removeLog(log.localTIDlogPath);
             destroy();
 
         } else {
 
             // Otherwise continue with reconstruction.
              = new RegisteredResources(this);
             .reconstruct(log);
 
             // Reconstruct the SuperiorInfo object.  This will result in a
             // call to RecoveryManager.addCoordinator (which is done
             // because reconstruction of the object references in the
             // SuperiorInfo requires the Coordinator to
             // already be known to the RecoveryManager).
 
              = new SuperiorInfo();
             .delegated_reconstruct(logthislogPath);
 
             // Cache the name  - create a buffer and print the
             // global XID into it.
 
              = ..toString();
 
             // Cache the hash value of the Coordinator.
 
              = ..hashCode();
         }
     }

    
Directs the TopCoordinator to perform recovery actions based on its reconstructed state after a failure, or after an in-doubt timeout has occurred. This method is called by the RecoveryManager during recovery, in which case there is no terminator object, or during normal operation if the transaction commit retry interval has been exceeded for the transaction. If this method is called more times than the retry limit specified in COMMITRETRY, then the global outcome of the transaction is taken from the value of HEURISTICDIRECTION.

Parameters:
isRoot A 1-element array which will be filled in with the root flag.
Returns:
The state of the recovered transaction.
See also:
 
     synchronized Status recover(boolean[/*1*/isRoot) {
 
         Status result;
 
         // Determine the global outcome using the transactions state for a root
         // Coordinator, or the RecoveryCoordinator for a subordinate.
 
         if (. != null) {
 
             // For a subordinate, first check whether the global
             // outcome is known locally.
 
 
             // GDH COP For the commit_one_phase operations we need to do the
             //         following ultimately. However for all c-o-p operations
             //         We know that the CLIENT/Superior chose to COMMIT.
             //         Also for all c-o-p operations that are  'past tense'
             //         the direction (commit or rolled back) is not really
             //         important as we are using c-o-p for single resources
             //         not last agent in CORBA CosTransactions.
             //
             // For clarity, all c-o-p states return a commited direction,
             // This is counter intuative but logicaly correct (unimportant)
             // even for COMMIT_ONE_PHASE_ROLLED_BACK.
             // A well behaved resource will not contact us in any of the
             // 'past tense' c-o-p states anyway as they have already returned
             // from a c-o-p op and can expect no further flows
             // (apart from forget perhaps).
             // When it comes to real resource flows we must be careful to
             // cause the following actions based on state:
             //
             // STATE_COMMITTING_ONE_PHASE
             // (We only ever enter this state if we have one resource
             // even if the c-o-p method was called on our CoordinatorResource)
             // The transaction was partway through a commit_one_phase
             // operation when the server failed.
             // So the commit_one_phase needs to be called again.
             // STATE COMMITTED_ONE_PHASE
             // STATE COMMITTED_ONE_PHASE_ROLLEDBACK
             // The transaction had just completed a commit_one_phase operation.
             // Therefore all of the work for the downstream part of the
             // transaction is over.  The only work to do is to possibly report
             // outcome to superior.
             // STATE COMMIT_ONE_PHASE_HEURISTIC_MIXED
             // STATE COMMIT_ONE_PHASE_HEURISTIC_HAZARD
             // Part of the tree has made a heuristic decision.  The forget
             // message must flow to all subordinate coordinators to allow them
             // to end.
 
             switch (.) {
 
             // GDH Due to the possibility of recovery being attempted
             // on more than one thread we must cover the case where
             // the transaction has actually COMMITTED already.
 
             case . :
                 // GDH (added)
             case . :
                 // GDH (added)
             case . :
                 // GDH (added)
             case . :
                 // GDH (added)
             case . :
                 result = Status.StatusCommitted;
                 break;
 
             // GDH Due to the possibility of recovery being attempted
             // on more than one thread we must cover the case where
             // the transaction has actually ROLLED_BACK already.
 
             case . :  // GDH (added)
             case . :
                 // GDH Note we do not need C-O-P_ROLLED_BACK Here as the actual
                 // resource rolling back will be done already so it's academic.
                 result = Status.StatusRolledBack;
                 break;
 
             // For a subordinate, the replay_completion method is invoked on
             // the superior's RecoveryCoordinator.  We may need to create a
             // CoordinatorResource object to give to the superior in the case
             // where we are in recovery. If the number of times
             // the replay_completion has bee retried is greater than the value
             // specified by COMMITRETRY, then HEURISTICDIRECTION is used
             // to determine the transaction outcome.
 
             default :
 
                 boolean attemptRetry = true;
                 // String commitRetryVar;
                 // int commitRetries = 0;
 
                 // If COMMITRETRY is not set, then retry is infinite.
                 // Otherwise check that
                 // the current number of retries is less than the limit.
 
               
commitRetryVar = Configuration. getPropertyValue(Configuration.COMMIT_RETRY); if (commitRetryVar != null) { try { commitRetries = Integer.parseInt(commitRetryVar); } catch( NumberFormatException exc ) {} if (superInfo.resyncRetries() >= commitRetries) { attemptRetry = false; } }
 
                 int commitRetries = Configuration.getRetries();
                 if (commitRetries >= 0 && (.resyncRetries() >= commitRetries))
                     attemptRetry = false;
 
 
                 if (!attemptRetry) {
 
                     // If we are not to attempt a retry of the
                     // replay_completion method, then the HEURISTICDIRECTION
                     // environment variable  is used to get the global outcome.
 
                     String heuristicVar;
                     boolean commitTransaction = false;
                     result = Status.StatusRolledBack;
 
                     heuristicVar =
                         Configuration.getPropertyValue(
                             .);
 
                     if (heuristicVar != null) {
                         commitTransaction = (heuristicVar.charAt(0) == '1');
                     }
 
                     if (commitTransaction) {
                         result = Status.StatusCommitted;
                     }
 
                 } else {
 
                     // Otherwise, use the RecoveryCoordinator to get
                     // the global outcome. Get the global outcome
                     // from the superior's RecoveryCoordinator.
 
                     try {
                     	{
 							.logp(.,"TopCoordinator","recover",
 									"Before invoking replay_completion on Superior Coordinator");
                     	}
                         if (!) {
                             result = ..
                                         replay_completion(.);
                         } else {
                             result = ((RecoveryCoordinatorImpl)(.)).
                                         replay_completion(.);
                         }
 
                         // GDH
                         // If the global result is returned as COMMITTING we
                         // know the outcome of the global transaction
                         // is COMMITTED.
 
                         if (result == Status.StatusCommitting) {
                             result = Status.StatusCommitted;
                         }
                     } catch (Throwable exc) {
                         // If the exception is neither TRANSIENT or
                         // COMM_FAILURE, it isunexpected, so display a message
                         // and assume that the transaction has rolled back.
 
                         if (!(exc instanceof COMM_FAILURE) &&
                                 !(exc instanceof TRANSIENT)) {
                             result = Status.StatusRolledBack;
                         } else {
                             // For TRANSIENT or COMM_FAILURE, the outcome
                             // is unknown.
                             result = Status.StatusUnknown;
                         }
                     }
                 }
 
                 break;
             }
 
             // Clear the root Coordinator flag to indicate that
             // this is not the root.
 
              = false;
 
         } else {
 
             // For a top-level Coordinator, we will generally only
             // recover in the case where we have successfully prepared.
             // If the state is not prepared_success,
             // then assume it is rollback.
 
             if (. == .) {
                 result = Status.StatusCommitted;
             } else {
                 result = Status.StatusRolledBack;
             }
 
             // Set the root Coordinator flag to indicate that this is the root.
 
              = true;
         }
 
         isRoot[0] = ;
 
         return result;
     }

    
Returns the local status of the target transaction.

Parameters:
Returns:
The status of the transaction.
See also:
 
     public Status get_status() {
 
         Status result = Status.StatusUnknown;
 
         if ( != null) {
 
             switch (.) {
 
             // If active, return active or marked rollback-only
             // if the flag is set.
 
             case . :
                 if )
                     result = Status.StatusMarkedRollback;
                 else
                     result = Status.StatusActive;
                 break;
 
             // If prepared, (successfully or otherwise), return prepared.
             // If committing return prepared (may want to block in this case).
 
             case . :
             case . :
             case . :
                 result = Status.StatusPrepared;
                 break;
 
             // If we have no internal state, return that fact.
             // All of these states map directly to the OMG values.
 
             case . :
                 result = Status.StatusNoTransaction;
                 break;
             case . :
             case . :
                 result = Status.StatusPreparing;
                 break;
             case . :
                 result = Status.StatusCommitting;
                 break;
             case . :
             case . :
                 result = Status.StatusCommitted;
                 break;
             case . :
             case . :
                 result = Status.StatusRollingBack;
                 break;
             case . :
                 result = Status.StatusRolledBack;
                 break;
 
             // Any other state, return unknown.
             // GDH Including c-o-p heuristic states
 
             default :
                 result = Status.StatusUnknown;
                 break;
             }
         } else {
             INVALID_TRANSACTION exc = new INVALID_TRANSACTION(
                                             .,
                                             .);
           throw exc;
         }
 
         return result;
     }

    
Gets the local state of the transaction. For a top-level transaction this operation is equivalent to the get_status method. This operation references no instance variables and so can be implemented locally in the proxy class.

Parameters:
Returns:
The status of the transaction.
See also:
 
     public Status get_parent_status() {
         Status result = get_status();
         return result;
     }

    
Gets the local state of the transaction. For a top-level transaction this operation is equivalent to the get_status method. This operation references no instance variables and so can be implemented locally in a proxy class.

Parameters:
Returns:
The status of the transaction.
See also:
 
     public Status get_top_level_status() {
 
         Status result = get_status();
         return result;
     }

    
Compares the given Coordinator object with the target, and returns TRUE if they represent the same transaction. This operation needs to be implemented in an efficient manner, without any cross-process calls. This could be achieved by including the global identifier in the Coordinator references and comparing them. This operation references no instance variables and so can be implemented locally in a proxy class.

Parameters:
other The other Coordinator to be compared.
Returns:
Indicates equality of the transactions the objects represent.
Throws:
SystemException The other Coordinator could not be reached.
See also:
 
removed synchronization at method level since only tranState requires locking
 
     public boolean is_same_transaction(Coordinator other)
             throws SystemException {
 
         boolean result = false;
 
         // Get the names of the two transactions and compare them.
 
         if ( != null) {
             if ( == null)
                  = ..toString();
             result = .equals(other.get_transaction_name());
         } else {
             INVALID_TRANSACTION exc = new INVALID_TRANSACTION(
                                             .,
                                             .);
             throw exc;
         }
 
         return result;
     }

    
Determines whether the target TopCoordinator is related to the given Coordinator (i.e. is a member of the same transaction family). For a top-level transaction returns TRUE if and only if the transaction associated with the parameter object is a descendant of the transaction associated with the target object. This operation references no instance variables and so can be implemented locally in a proxy class.

Parameters:
other The other Coordinator.
Returns:
Indicates the relationship.
Throws:
org.omg.CORBA.SystemException The other Coordinator could not be reached.
See also:
    public boolean is_related_transaction(Coordinator other)
            throws SystemException {
        boolean result = false;
        if ( != null) {
            result = other.is_descendant_transaction(this.object());
        } else {
            INVALID_TRANSACTION exc = new INVALID_TRANSACTION(
                                            .,
                                            .);
            throw exc;
        }
        return result;
    }

    
Determines whether this TopCoordinator is the root TopCoordinator. the given Coordinator (i.e. is a member of the same transaction family). For a root transaction, this method returns TRUE. Otherwise it returns FALSE.

Returns:
Indicates if this is the root TopCoordinator.
See also:
    public boolean is_root_transaction() {
        boolean result = ;
        return result;
    }

    
Determines whether the target TopCoordinator is an ancestor of the given Coordinator. For a top-level transaction returns TRUE if and only if the transaction associated with the target object is an ancestor of the transaction associated with the parameter object. This operation references no instance variables and so can be implemented locally in a proxy class.

Parameters:
other The other Coordinator.
Returns:
Indicates the relationship.
Throws:
org.omg.CORBA.SystemException The other Coordinator could not be reached.
See also:
    public boolean is_ancestor_transaction(Coordinator other)
            throws SystemException {
        boolean result = false;
        if ( != null) {
          result = other.is_descendant_transaction(this.object());
        } else {
            INVALID_TRANSACTION exc = new INVALID_TRANSACTION(
                                            .,
                                            .);
            throw exc;
        }
        return result;
    }

    
Determines whether the target TopCoordinator is a descendant of the given Coordinator. For a top-level transaction returns TRUE if and only if the transaction associated with the target object is the same as the transaction associated with the parameter object. This operation references no instance variables and so can be implemented locally in a proxy class.

Parameters:
other The other Coordinator.
Returns:
Indicates the relationship.
Throws:
org.omg.CORBA.SystemException The other Coordinator could not be reached.
See also:
    public boolean is_descendant_transaction(Coordinator other)
            throws SystemException {
        boolean result = false;
        if ( != null) {
            result = is_same_transaction(other);
        } else {
            INVALID_TRANSACTION exc = new INVALID_TRANSACTION(
                                            .,
                                            .);
            throw exc;
        }
        return result;
    }

    
Determines whether the target TopCoordinator represents a top-level (non-nested) transaction.

For a top-level transaction returns TRUE.

This operation references no instance variables and so can be implemented locally in a proxy class.

Parameters:
Returns:
Indicates this is a top-level transaction.
See also:
    public boolean is_top_level_transaction() {
        boolean result = true;
        return result;
    }

    
Returns a hash value based on the transaction associated with the target object. This operation references only the global TID, and so can be implemented locally in a proxy class.

Parameters:
Returns:
The hash value for the transaction.
See also:
removed synchronization at method level since only tranState requires locking
    public int hash_transaction() {
        int result = ;
        if ( == null) {
            INVALID_TRANSACTION exc = new INVALID_TRANSACTION(
                                            .,
                                            .);
            throw exc;
        }
        return result;
    }

    
Returns a hash value based on the top-level ancestor of the transaction associated with the target object. This operation references only the global TID, and so can be implemented locally in a proxy class.

Parameters:
Returns:
The hash value for the transaction.
See also:
    synchronized public int hash_top_level_tran() {
        int result = ;
        if ( == null) {
            INVALID_TRANSACTION exc = new INVALID_TRANSACTION(
                                            .,
                                            .);
            throw exc;
        }
        return result;
    }

    
Enables a Resource to be registered as a participant in the completion of the top-level transaction represented by the TopCoordinator. If the TopCoordinator is a subordinate, and has not registered with its superior, it creates a CoordinatorResource and registers it. The RecoveryCoordinator that is returned is stored in the SuperiorInfo.

Parameters:
res The Resource to be registered.
Returns:
The RecoveryCoordinator object from the registration with the top-level ancestor.
Throws:
Inactive The Coordinator is completing the transaction and cannot accept this registration.
org.omg.CORBA.TRANSACTION_ROLLEDBACK The transaction which the Coordinator represents has already been rolled back, or has been marked rollback-only.
See also:
    synchronized public RecoveryCoordinator register_resource(Resource res)
            throws Inactive, TRANSACTION_ROLLEDBACK {
        RecoveryCoordinator result = null;
        // First check the state of the transaction. If it is not active,
        // do not allow the registration.
        if ( == null || . !=
                .) {
          Inactive exc = new Inactive();
          throw exc;
        }
        // Check whether the transaction has been marked rollback-only.
        if () {
            TRANSACTION_ROLLEDBACK exc =
                new TRANSACTION_ROLLEDBACK(0, .);
            throw exc;
        }
        // If not previously registered, a CoordinatorResource object must be
        // registered with our superior.  Note that root TopCoordinators are
        // created with the registration flag set, so we do not need to
        // check whether we are the root TopCoordinator here.
        if (! && DefaultTransactionService.isORBAvailable()) {
            // Initialise the CoordinatorResource with the local id,
            // our reference, and a flag to indicate that it does not
            // represent a subtransaction.
            CoordinatorResourceImpl cImpl =
                new CoordinatorResourceImpl(.thisfalse);
            try {
                // Register the CoordinatorResource with the superior
                // Coordinator, and store the resulting RecoveryCoordinator
                // reference.
                CoordinatorResource cRes = cImpl.object();
                RecoveryCoordinator superRecovery =
                    ..register_resource(cRes);
		if (!(superRecovery instanceof TxInflowRecoveryCoordinator))
                    .setRecovery(superRecovery);
                .setResource(cRes);
                 = true;
                {
                    .logp(.,"TopCoordinator","register_resource()",
							"CoordinatorResource " + cImpl + 
							" has been registered with (Root)TopCoordinator"+
                }
            } catch (Exception exc) {
                // If an exception was raised, do not store the
                // RecoveryCoordinator or set the registration flag.
                // Throw an internal exception.
                cImpl.destroy();
                if (exc instanceof OBJECT_NOT_EXIST) {
                    // If the exception is a system exception, then allow it
                    // to percolate to the caller.
                    TRANSACTION_ROLLEDBACK ex2 =
                        new TRANSACTION_ROLLEDBACK(
                            0, .);
                    ex2.initCause(exc);
                    throw ex2;
                }
                if (exc instanceof Inactive)  {
                    throw (Inactive)exc;
                }
                if (exc instanceof SystemException) {
                    throw (SystemException)exc;
                }
                // Otherwise throw an internal exception.
                INTERNAL ex2 = new INTERNAL(.,
                                            .);
                ex2.initCause(exc);
                throw ex2;
            }
        }
        // If the set has not already been created, create it now.
        if ( == null) {
             = new RegisteredResources(this);
        }
        // Add a duplicate of the reference to the set.  This is done
        // because if the registration is for a remote object, the proxy
        // will be freed when the registration request returns.
        // COMMENT(Ram J) if the res object is a local servant, there is
        // no proxy involved. Also, the instanceof operator could be replaced
        // by a is_local() method if this class implements the CORBA local
        // object contract.
        int numRes = 0;
        if (res instanceof OTSResourceImpl) {
            numRes = .addRes(res);
            {
				.logp(.,"TopCoordinator","register_resource()",
						"OTSResource " + res +" has been registered"+"GTID is:"+
            }
        } else {
            numRes = .addRes((Resource)res._duplicate());
        }
         = false;
        // Create, initialise and return a RecoveryCoordinator
        // object to the caller.
        // COMMENT(Ram J) a RecoveryCoordinator object need not be
        // created for local resources.
        if (!(res instanceof OTSResourceImpl)) {
            RecoveryCoordinatorImpl rcImpl = null;
            try {
                rcImpl = new RecoveryCoordinatorImpl(
                                            .numRes);
                result = rcImpl.object();
            } catch (Exception exc) {
                // If the RecoveryCoordinator could not be created,
                // report the exception.
                INTERNAL ex2 = new INTERNAL(.,
                                            .);
                throw ex2;
            }
            // ADD(Ram J) memory leak fix. All Recovery Coordinators need
            // to be cleanedup when the transaction completes.
            if ( == null) {
                 = new Vector();
            }
            .add(rcImpl);
        }
        return result;
    }

    
Enables a SubtransactionAwareResource to be registered as a participant in the completion of a subtransaction. For a top-level transaction this raises the NotSubtransaction exception.

Parameters:
sares The SubtransactionAwareResource to be registered.
Returns:
Throws:
NotSubtransaction The Coordinator represents a top-level transaction and cannot accept the registration.
See also:
    synchronized public void register_subtran_aware(
            SubtransactionAwareResource saresthrows NotSubtransaction {
        NotSubtransaction exc = new NotSubtransaction();
        throw exc;
    }

    
Ensures that the transaction represented by the target TopCoordinator cannot be committed.

Parameters:
Returns:
Throws:
Inactive The Coordinator is already completing the transaction.
See also:
     public void rollback_only() throws Inactive {
        if ( == null ||
                . != .) {
            Inactive exc = new Inactive();
            throw exc;
        } else {
            // Set the rollback-only flag.
             = true;
        }
    }

    
Returns a printable string that represents the TopCoordinator. This operation references only the global TID, and so can be implemented locally in a proxy class.

Parameters:
Returns:
The transaction name.
See also:
removed synchronization at method level since only tranState requires locking
    public String get_transaction_name() {
        String result = null;
        if ( != null) {
            if ( == null)
                 = ..toString();
            result = new String();
        } else {
            INVALID_TRANSACTION exc = new INVALID_TRANSACTION(
                                            .,
                                            .);
            throw exc;
        }
        return result;
    }

    
Creates a subtransaction and returns a Control object that represents the child transaction.

Parameters:
Returns:
The Control object for the new child transaction.
Throws:
Inactive The Coordinator is completing the subtransaction and cannot create a new child.
See also:
    synchronized public Control create_subtransaction() throws Inactive {
        Control result = null;
        // First check the state of the transaction. If it is not active,
        // do not allow the subtransaction to be created.
        if ( == null ||
                . != .) {
            Inactive exc = new Inactive();
            throw exc;
        }
        // Set up the sequence of ancestors to hold the single reference
        // and global identifier of the top-level
        // TopCoordinator as there are no ancestors.
        // We do not need to make a copy of the global TID as this is done
        // by the factory when it creates the child.
        CoordinatorImpl[] ancestors = new CoordinatorImpl[1];
        ancestors[0] = this;
        // Create a new SubCoordinator, and initialise it with the given
        // identifiers and ancestry.  If the operation fails,
        // return a NULL Control object, and
        // the SubtransactionsUnavailable exception. Note that the
        // ancestor sequence is not copied by the creation operation.
        SubCoordinator child = null;
        TerminatorImpl terminator = null;
        try {
            child = new SubCoordinator(.,
                                       .,
                                       ancestors);
            // Create a Terminator object, and initialise it with the
            // SubCoordinator reference and a flag to indicate that it
            // represents a subtransaction.
            terminator = new TerminatorImpl(child,true);
            // Create a Control object, and initialise it with the Terminator,
            // SubCoordinator and global OMGtid.
            result = new ControlImpl(terminatorchild,
                                     new GlobalTID(child.getGlobalTID()),
                                     new Long(child.getLocalTID())