All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.jts.CosTransactions.CoordinatorTerm Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2012 Oracle and/or its affiliates. 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_1_1.html
 * or packager/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 packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [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.
 */

//----------------------------------------------------------------------------
//
// Module:      CoordinatorTerm.java
//
// Description: Client Coordinator termination.
//
// 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 required classes.

import org.omg.CORBA.*;
import org.omg.CosTransactions.*;
import com.sun.jts.trace.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import com.sun.logging.LogDomains;
import com.sun.jts.utils.LogFormatter;

/**The CoordinatorTerm interface provides operations that allow an
 * Terminator to direct completion of a transaction without any dependency
 * on the Coordinator interface.
 *
 * @version 0.01
 *
 * @author Simon Holdsworth, IBM Corporation
 *
 * @see
*/
//----------------------------------------------------------------------------
// CHANGE HISTORY
//
// Version By     Change Description
//   0.01  SAJH   Initial implementation.
//------------------------------------------------------------------------------

class CoordinatorTerm implements CompletionHandler {
    private CoordinatorImpl coordinator = null;
    private boolean         subtransaction = false;
    private boolean         aborted = false;
    private boolean         heuristicDamage = false;
    private boolean         completed = false;
    private boolean         completing = false;

	/*
		Logger to log transaction messages
	*/ 
	
	static Logger _logger = LogDomains.getLogger(CoordinatorTerm.class, LogDomains.TRANSACTION_LOGGER);

    /**Default CoordinatorTerm constructor.
     *
     * @param
     *
     * @return
     *
     * @see
     */
    CoordinatorTerm() {
    }

    /**Normal constructor.
     * 

* Sets up the CoordinatorTerm with the Coordinator reference so that the * CoordinatorTerm can find the Coordinator to pass on the two-phase commit * messages. *

* A flag is passed to indicate whether the CoordinatorTerm * represents a subtransaction. * * @param coord The Coordinator for the transaction. * @param subtran The subtransaction indicator. * * @return * * @see */ CoordinatorTerm( CoordinatorImpl coord, boolean subtran ) { // Set up the instance variables from the values passed. coordinator = coord; subtransaction = subtran; // Inform the Coordinator that this is the object that normally terminates // the transaction. if( coordinator != null ) coordinator.setTerminator(this); } /**Informs the object that the transaction is to be committed. *

* Uses a private interface to pass the Terminator's commit request on to the * Coordinator. *

* This operation does not check for outstanding requests, that is done by * the Current operations (when the client is using direct interaction we * cannot provide checked behavior). *

* Before telling the Coordinator to commit, it is informed that the * transaction is about to complete, and afterwards it is told that the * transaction has completed, with an indication of commit or rollback. * * @param promptReturn Indicates whether to return promptly. * * @return * * @exception TRANSACTION_ROLLEDBACK The transaction could not be committed and * has been rolled back. * @exception HeuristicHazard Heuristic action may have been taken by a * participant in the transaction. * @exception HeuristicMixed Heuristic action has been taken by a participant * in the transaction so part of the transaction has * been rolled back. * @exception SystemException An error occurred calling another object. * @exception LogicErrorException An internal logic error occurred. * * @see */ void commit( boolean promptReturn ) throws HeuristicMixed, HeuristicHazard, TRANSACTION_ROLLEDBACK, SystemException, LogicErrorException { // BUGFIX(Ram J) (12/16/2000) This was previously set to true, which the // caused commit_one_phase exceptions not to be reported. boolean commit_one_phase_worked_ok = false; // If the transaction that this object represents has already been rolled // back, raise the TRANSACTION_ROLLEDBACK exception and return. // If the transaction completed with heuristic damage, report that. if( aborted ) { throw new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO); } // If there is no Coordinator reference, raise an exception. if( coordinator == null ) { String msg = LogFormatter.getLocalizedMessage(_logger, "jts.no_coordinator_available"); LogicErrorException exc = new LogicErrorException(msg); throw exc; } // Remember that it is us that have initiated the completion so that we can // ignore the aborted operation if it happens subsequently. completing = true; // Determine the current Control object and Coordinator. Determine whether // the current transaction is the same as that being committed. ControlImpl current = CurrentTransaction.getCurrent(); ControlImpl establishedControl = null; Coordinator currentCoord = null; boolean sameCoordinator = false; if( current != null ) try { if (Configuration.isLocalFactory()) { currentCoord = current.get_localCoordinator(); } else { currentCoord = current.get_coordinator(); } sameCoordinator = coordinator.is_same_transaction(currentCoord); } catch( Unavailable exc ) {} // We must ensure that there is a current transaction at this point if it is a // top-level transaction because the Synchronization objects expect to have // transaction context. // If this CoordinatorTerm was created by a Factory, then this commit will // not have context because the Terminator is not a transactional object. RuntimeException rte = null; if( !subtransaction ) { try { if( current == null || !sameCoordinator ) { establishedControl = new ControlImpl(null,coordinator, new GlobalTID(coordinator.getGlobalTID()), coordinator.getLocalTID()); CurrentTransaction.setCurrent(establishedControl,true); } } catch( Throwable exc ) { } // Tell the Coordinator that the transaction is about to complete. try { ((TopCoordinator)coordinator).beforeCompletion(); } // If the Coordinator raised an exception, return it to the caller. catch( SystemException exc ) { completing = false; throw exc; } catch (RuntimeException exc) { rte = exc; } // If a temporary context was established, end it now. finally { if( establishedControl != null ) { CurrentTransaction.endCurrent(true); establishedControl.doFinalize(); } } } // End the association of the current Control object with the current thread // if it is the same transaction as the one being committed. // This is done here rather than in Current because the before completion // method must be invoked while the transaction is still active. Status status = Status.StatusCommitted; if( sameCoordinator ) CurrentTransaction.endCurrent(true); // Now, process the actual 2PC Throwable heuristicExc = null; Throwable otherExc = null; // GDH Now see if we can legally call commit one phase // the commitOnePhase method will return false if this is // not possible. if (rte == null) { try { commit_one_phase_worked_ok = coordinator.commitOnePhase(); } catch( Throwable exc ) { if( exc instanceof HeuristicHazard || exc instanceof HeuristicMixed ) { heuristicExc = exc; } else if( exc instanceof TRANSACTION_ROLLEDBACK ) { status = Status.StatusRolledBack; } else if( exc instanceof INVALID_TRANSACTION ) { // Why have we driven before completion before now? throw (INVALID_TRANSACTION)exc; } if (exc instanceof INTERNAL) { // ADDED(Ram J) percolate any system exception // back to the caller. otherExc = exc; //throw (INTERNAL) exc; }else { } } } if( commit_one_phase_worked_ok ) { // Then we have done the commit already above // Set the status for the after completion call // even though currently the parm is not used // inside the call - it get's the state from transtate // the status variable here is a local flag. status = Status.StatusCommitted; // GDH COPDEF1 Added this for neatness } else if (status != Status.StatusRolledBack) { // Added (Ram J) (12/06/2000) // commit two phase now // Get the prepare vote from the root Coordinator. Vote prepareResult = Vote.VoteRollback; if (rte == null) { try { prepareResult = coordinator.prepare(); } catch( HeuristicHazard exc ) { heuristicExc = exc; } catch( HeuristicMixed exc ) { heuristicExc = exc; } catch( INVALID_TRANSACTION exc ) { otherExc = exc; //throw exc; } catch( INTERNAL exc ) { otherExc = exc; //throw exc; } catch( Throwable exc ) { } } if( subtransaction ) { // Depending on the prepare result, commit or abort the transaction. if( prepareResult == Vote.VoteCommit ) try { if(_logger.isLoggable(Level.FINE)) { _logger.logp(Level.FINE,"CoordinatorTerm","commit()", "Before invoking coordinator.commit() :"+"GTID is: "+ ((TopCoordinator)coordinator).superInfo.globalTID.toString()); } coordinator.commit(); } catch( NotPrepared exc ) { prepareResult = Vote.VoteRollback; } if( prepareResult == Vote.VoteRollback ) { if(_logger.isLoggable(Level.FINE)) { _logger.logp(Level.FINE,"CoordinatorTerm","commit()", "Before invoking coordinator.rollback :"+ "GTID is : "+ ((TopCoordinator)coordinator).superInfo.globalTID.toString()); } coordinator.rollback(true); status = Status.StatusRolledBack; } } // End of dealing with top-level transactions. else { // Depending on the prepare result, commit or abort the transaction. //$ DO SOMETHING ABOUT PROMPT RETURN */ try { if( prepareResult == Vote.VoteCommit ) { try { coordinator.commit(); } catch( NotPrepared exc ) { prepareResult = Vote.VoteRollback; } } if( prepareResult == Vote.VoteRollback && heuristicExc == null ) { status = Status.StatusRolledBack; // GDH COPDEF1 Swapped these two lines coordinator.rollback(true); // (not stricly necessary for problem fix) } } catch( Throwable exc ) { if (exc instanceof HeuristicHazard || exc instanceof HeuristicMixed) { heuristicExc = exc; } // ADDED(Ram J) percolate any system exception // back to the caller. if (exc instanceof INTERNAL) { otherExc = exc; //throw (INTERNAL) exc; } } } // end else was top level txn } // end else used two phase else // Tell the Coordinator that the transaction has completed (top-level // transactions only). if( !subtransaction ) { ((TopCoordinator)coordinator).afterCompletion(status); } // Inform the Control object that the transaction has completed. completed = true; if( current != null && sameCoordinator ) current.setTranState(status); // If a heuristic was thrown, throw the exception. if( heuristicExc != null ) { if( heuristicExc instanceof HeuristicMixed ) throw (HeuristicMixed)heuristicExc; else throw (HeuristicHazard)heuristicExc; } else if( otherExc != null ) { if (otherExc instanceof INVALID_TRANSACTION) throw (INVALID_TRANSACTION) otherExc; else if (otherExc instanceof INTERNAL) throw (INTERNAL) otherExc; } // If the transaction was rolled back, raise an exception. if( status == Status.StatusRolledBack ) { TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_YES); if (rte != null) { exc.initCause(rte); } throw exc; } } /**Informs the object that the transaction is to be rolled back. *

* Uses a private interface to pass the Terminator's rollback request on to * the Coordinator. * * @param * * @return * * @exception HeuristicHazard Heuristic action may have been taken by a * participant in the transaction. * @exception HeuristicMixed Heuristic action has been taken by a participant * in the transaction so part of the transaction has * been committed. * @exception SystemException An error occurred calling another object. * @exception LogicErrorException An internal logic error occurred. * * @see */ void rollback() throws HeuristicMixed, HeuristicHazard, SystemException, LogicErrorException { // If the transaction that this object represents has already been rolled // back, raise an exception. Note that we cannot raise a heuristic exception // here as it is not in the OMG interface. if( aborted ) { TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO); throw exc; } // If there is no Coordinator reference, raise an exception. if( coordinator == null ) { String msg = LogFormatter.getLocalizedMessage(_logger, "jts.no_coordinator_available"); LogicErrorException exc = new LogicErrorException(msg); throw exc; } // Remember that it is us that have initiated the completion so that we can // ignore the aborted operation if it happens subsequently. Coordinator currentCoord = null; ControlImpl current = null; completing = true; // End the association of the current Control object with the current thread // if it is the same transaction as the one being committed. try { current = CurrentTransaction.getCurrent(); } catch( Throwable exc ) {} if( current != null ) try { if (Configuration.isLocalFactory()) { currentCoord = current.get_localCoordinator(); } else { currentCoord = current.get_coordinator(); } if( coordinator.is_same_transaction(currentCoord) ) CurrentTransaction.endCurrent(true); } // If an exception was raised, it must be because the transaction that the // current Control object represents was rolled back. In that case, always // end the current thread association. catch( Throwable exc ) { CurrentTransaction.endCurrent(true); } // Rollback the transaction and inform synchronisation objects. Throwable heuristicExc = null; try { coordinator.rollback(true); } catch (Throwable exc) { if (exc instanceof HeuristicHazard || exc instanceof HeuristicMixed) { heuristicExc = exc; } // ADDED (Ram J) percolate any system exception to the caller if (exc instanceof INTERNAL) { throw (INTERNAL) exc; } } finally { if( !subtransaction ) ((TopCoordinator)coordinator).afterCompletion(Status.StatusRolledBack); } // Inform the Control object that the transaction has completed. completed = true; if( current != null ) current.setTranState(Status.StatusRolledBack); // If a heuristic was thrown, throw the exception. if( heuristicExc != null ) { if( heuristicExc instanceof HeuristicMixed ) throw (HeuristicMixed)heuristicExc; else throw (HeuristicHazard)heuristicExc; } // Otherwise return normally. } /**Informs the CoordinatorTerm object that the transaction it represents * has completed. *

* Flags indicate whether the transaction aborted, and * whether there was heuristic damage. *

* This operation is invoked by a Coordinator when it is rolled back, * potentially by a caller other than the CoordinatorTerm itself. In the * event that it is some other caller, the CoordinatorTerm object performs the * after rollback synchronisation, and remembers the fact that it has aborted * for later. * * @param aborted Indicates whether the transaction locally aborted. * @param heuristicDamage Indicates local heuristic damage. * * @return * * @see */ public void setCompleted( boolean aborted, boolean heuristicDamage ) { // If the transaction that this object represents has already been rolled // back, or is being rolled back by this object, just return. if( !completing ) { // If there is no Coordinator reference, we cannot do anything. Note that // CompletionHandler does not permit an exception through this method so we // cannot throw one. // Set the flags and distribute after completion operations for the // transaction. completed = true; this.aborted = aborted; this.heuristicDamage = heuristicDamage; if( coordinator == null ) { } else if( !subtransaction ) ((TopCoordinator)coordinator).afterCompletion(Status.StatusRolledBack); } } /**Dumps the state of the object. * * @param * * @return * * @see */ void dump() { } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy