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

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

There is a newer version: 8.0.0-JDK17-M9
Show newest version
/*
 * Copyright (c) 2022 Contributors to the Eclipse Foundation
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1995-1997 IBM Corp. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

//----------------------------------------------------------------------------
//
// Module:      CurrentImpl.java
//
// Description: Transaction Current pseudo-object implementation.
//
// Product:     com.sun.jts.CosTransactions
//
// Author:      Simon Holdsworth
//
// Date:        March, 1997
//----------------------------------------------------------------------------

package com.sun.jts.CosTransactions;

import com.sun.jts.codegen.otsidl.JControl;
import com.sun.jts.codegen.otsidl.JControlHelper;
import com.sun.logging.LogDomains;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.INVALID_TRANSACTION;
import org.omg.CORBA.NO_PERMISSION;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.TRANSACTION_ROLLEDBACK;
import org.omg.CosTransactions.Control;
import org.omg.CosTransactions.Coordinator;
import org.omg.CosTransactions.HeuristicHazard;
import org.omg.CosTransactions.HeuristicMixed;
import org.omg.CosTransactions.InvalidControl;
import org.omg.CosTransactions.NoTransaction;
import org.omg.CosTransactions.Status;
import org.omg.CosTransactions.StatusHolder;
import org.omg.CosTransactions.SubtransactionsUnavailable;
import org.omg.CosTransactions.Terminator;
import org.omg.CosTransactions.TransactionFactory;
import org.omg.CosTransactions.Unavailable;

/**The CurrentImpl class is our implementation of the standard Current
 * interface. It provides operations that enable the demarcation of a
 * transaction's scope. These operations are specified in pseudo-IDL. The
 * CurrentImpl ensures that the CurrentTransaction class is set up when the
 * CurrentImpl is created. As an instance of this class may be accessed from
 * multiple threads within a process, serialisation for thread-safety is
 * necessary in the implementation.
 *
 * @version 0.01
 *
 * @author Simon Holdsworth, IBM Corporation
 *
 * @see
*/
//----------------------------------------------------------------------------
// CHANGE HISTORY
//
// Version By     Change Description
//   0.01  SAJH   Initial implementation.
//-----------------------------------------------------------------------------

public class CurrentImpl extends org.omg.CORBA.LocalObject
implements org.omg.CosTransactions.Current {
    private int timeOut = 0;
    private static boolean active = true;
    private TransactionFactory factory = null;
    /*
        Logger to log transaction messages
     */
    static Logger _logger = LogDomains.getLogger(CurrentImpl.class, LogDomains.TRANSACTION_LOGGER);

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

        // Ensure the CurrentTransaction state has been initialised.

        CurrentTransaction.initialise();
    }

    /**Creates a new Control object, containing new Terminator and Coordinator
     * objects.
     * 

* The current timeout value is passed to the Coordinator. *

* The Control object is made the current one for the thread on which this * method was invoked. If there is already a current Control the existing * Control that represents the parent transaction is stacked behind the new one, * which becomes the current one. * * @param * * @return * * @exception SubtransactionsUnavailable A subtransaction cannot be begun, * either because the Transaction Service does not support nested transactions * or because the current transaction is completing. * @exception INVALID_TRANSACTION The transaction could not be begun as the * current thread of control has pending non-transactional work. * @exception SystemException The operation failed. * * @see */ @Override public void begin() throws INVALID_TRANSACTION, SystemException, SubtransactionsUnavailable { ControlImpl controlImpl = null; // Until we need to check for resync in progress, synchronize the method. synchronized(this) { // If the transaction service is not active, throw an exception. if( !active ) { NO_PERMISSION exc = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO); throw exc; } if (Configuration.isDBLoggingEnabled()) { //Put a marker record into the log table LogDBHelper.getInstance().setServerName(); } // Get a reference to the current ControlImpl object. try { controlImpl = CurrentTransaction.getCurrent(); } catch( SystemException exc ) { } // Release the lock now so that if the TransactionFactoryImpl call has to block // (during resync), the lock does not prevent other threads from running. } // If there is a current Control object, then we should try to begin a // subtransaction. if( controlImpl != null ) { try { // Get the Coordinator reference, and use it to create a subtransaction. // If an exception was raised, return it to the caller. Coordinator coord = controlImpl.get_coordinator(); // Create a new Control object to represent the subtransaction. Control control = coord.create_subtransaction(); // This control object may be remote, if the original Control object was. // In this case we need to deal with it in the same was as we do in the // resume method. Any exception which is thrown during this process will // result in SubtransactionsUnavailable thrown to the caller. JControl jcontrol = JControlHelper.narrow(control); if( jcontrol != null ) { controlImpl = ControlImpl.servant(jcontrol); } // If there is no local ControlImpl object for the transaction, we create one // now. if( controlImpl == null ) { controlImpl = new ControlImpl(control); } } catch( Throwable exc ) { SubtransactionsUnavailable ex2 = new SubtransactionsUnavailable(); throw ex2; } } else { //$ CurrentTransaction.report(); //$ RecoveryManager.report(); //$ ControlImpl.report(); //$ CoordinatorLog.report(); //$ TimeoutManager.report(); // try { // Get the TransactionFactory which should be used from this application. // This block must be synchronized so that different threads do not try // this concurrently. synchronized(this) { if( factory == null ) { factory = Configuration.getFactory(); } } // Create the new transaction. if (factory != null) { if(_logger.isLoggable(Level.FINEST)) { _logger.logp(Level.FINEST,"CurrentImpl","begin()", "Before invoking create() on TxFactory"); } if (Configuration.isLocalFactory()) { controlImpl = ((TransactionFactoryImpl) factory).localCreate(timeOut); } else { Control control = factory.create(timeOut); // This control object is remote. // In this case we need to deal with it in the same was as we do in the // resume method. Any exception which is thrown during this process will // result in SubtransactionsUnavailable thrown to the caller. JControl jcontrol = JControlHelper.narrow(control); if (jcontrol != null) { controlImpl = ControlImpl.servant(jcontrol); } // If there is no local ControlImpl object for the transaction, we create one // now. if (controlImpl == null) { controlImpl = new ControlImpl(control); } } } } catch( Throwable exc ) { _logger.log(Level.WARNING, "jts.unexpected_error_in_begin",exc); } } // If the new Control reference is NULL, raise an error at this point. if( controlImpl == null ){ INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.FactoryFailed, CompletionStatus.COMPLETED_NO); throw exc; } else { try { if(_logger.isLoggable(Level.FINEST)) { _logger.logp(Level.FINEST,"CurrentImpl","begin()", "Before invoking CurrentTransaction.setCurrent(control,true)"); } CurrentTransaction.setCurrent(controlImpl,true); } // The INVALID_TRANSACTION exception at this point indicates that the transaction // may not be started. Clean up the state of the objects in the transaction. catch( INVALID_TRANSACTION exc ) { controlImpl.destroy(); throw (INVALID_TRANSACTION)exc.fillInStackTrace(); } } } //START RI PERFIMPROVEMENT // This method is introduced to improve the performance. without this method external // synchronization is required to associate the timeout with this transaction // This method is not part of the standard Current interface /**Creates a new Control object, containing new Terminator and Coordinator * objects. *

* Input parameter timeout value is passed to the Coordinator. *

* The Control object is made the current one for the thread on which this * method was invoked. If there is already a current Control the existing * Control that represents the parent transaction is stacked behind the new one, * which becomes the current one. * * @param * * @return * * @exception SubtransactionsUnavailable A subtransaction cannot be begun, * either because the Transaction Service does not support nested transactions * or because the current transaction is completing. * @exception INVALID_TRANSACTION The transaction could not be begun as the * current thread of control has pending non-transactional work. * @exception SystemException The operation failed. * * @see */ public void begin(int time_out) throws INVALID_TRANSACTION, SystemException, SubtransactionsUnavailable { ControlImpl controlImpl = null; // Until we need to check for resync in progress, synchronize the method. synchronized(this) { // If the transaction service is not active, throw an exception. if( !active ) { NO_PERMISSION exc = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO); throw exc; } if (Configuration.isDBLoggingEnabled()) { //Put a marker record into the log table LogDBHelper.getInstance().setServerName(); } // Get a reference to the current ControlImpl object. try { controlImpl = CurrentTransaction.getCurrent(); } catch( SystemException exc ) { } // Release the lock now so that if the TransactionFactoryImpl call has to block // (during resync), the lock does not prevent other threads from running. } // If there is a current Control object, then we should try to begin a // subtransaction. if( controlImpl != null ) { try { // Get the Coordinator reference, and use it to create a subtransaction. // If an exception was raised, return it to the caller. Coordinator coord = controlImpl.get_coordinator(); // Create a new Control object to represent the subtransaction. Control control = coord.create_subtransaction(); // This control object may be remote, if the original Control object was. // In this case we need to deal with it in the same was as we do in the // resume method. Any exception which is thrown during this process will // result in SubtransactionsUnavailable thrown to the caller. JControl jcontrol = JControlHelper.narrow(control); if( jcontrol != null ) { controlImpl = ControlImpl.servant(jcontrol); } // If there is no local ControlImpl object for the transaction, we create one // now. if( controlImpl == null ) { controlImpl = new ControlImpl(control); } } catch( Throwable exc ) { SubtransactionsUnavailable ex2 = new SubtransactionsUnavailable(); throw ex2; } } else { //$ CurrentTransaction.report(); //$ RecoveryManager.report(); //$ ControlImpl.report(); //$ CoordinatorLog.report(); //$ TimeoutManager.report(); // try { // Get the TransactionFactory which should be used from this application. // This block must be synchronized so that different threads do not try // this concurrently. synchronized(this) { if( factory == null ) { factory = Configuration.getFactory(); } } // Create the new transaction. if (factory != null) { if(_logger.isLoggable(Level.FINEST)) { _logger.logp(Level.FINEST,"CurrentImpl","begin()", "Before invoking create() on TxFactory"); } if (Configuration.isLocalFactory()) { controlImpl = ((TransactionFactoryImpl) factory).localCreate(time_out); } else { Control control = factory.create(time_out); // This control object is remote. // In this case we need to deal with it in the same was as we do in the // resume method. Any exception which is thrown during this process will // result in SubtransactionsUnavailable thrown to the caller. JControl jcontrol = JControlHelper.narrow(control); if (jcontrol != null) { controlImpl = ControlImpl.servant(jcontrol); } // If there is no local ControlImpl object for the transaction, we create one // now. if (controlImpl == null) { controlImpl = new ControlImpl(control); } } } } catch( Throwable exc ) { _logger.log(Level.WARNING, "jts.unexpected_error_in_begin",exc); } } // If the new Control reference is NULL, raise an error at this point. if (controlImpl == null) { throw new INVALID_TRANSACTION(MinorCode.FactoryFailed, CompletionStatus.COMPLETED_NO); } try { if (_logger.isLoggable(Level.FINEST)) { _logger.logp(Level.FINEST, "CurrentImpl", "begin()", "Before invoking CurrentTransaction.setCurrent(control,true)"); } CurrentTransaction.setCurrent(controlImpl,true); } catch (INVALID_TRANSACTION exc) { // The INVALID_TRANSACTION exception at this point indicates that the transaction // may not be started. Clean up the state of the objects in the transaction. controlImpl.destroy(); throw exc; } } //END RI PERFIMPROVEMENT /**Completes the current transaction. *

* This operation can only be called if there is a Terminator object available. * * @param reportHeuristics Indicates that heuristic exceptions should be * passed back to the caller. * * @return * * @exception NoTransaction There is no current transaction to commit. * @exception INVALID_TRANSACTION The current transaction has outstanding * work and the Transaction Service is "checked". * @exception NO_PERMISSION The caller is not allowed to commit the * transaction. * @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. * @exception SystemException The operation failed. * * @see */ @Override public void commit( boolean reportHeuristics ) throws NO_PERMISSION, INVALID_TRANSACTION, TRANSACTION_ROLLEDBACK, NoTransaction, HeuristicHazard, HeuristicMixed, SystemException { // Get the current Control object. If there is none, raise the // NoTransaction exception and return. ControlImpl controlImpl = CurrentTransaction.getCurrent(); if( controlImpl == null ) { NoTransaction exc = new NoTransaction(); throw exc; } // Get the local identifier from the Control object. Raise an exception if // the transaction the Control represents has been completed. int active = 1; if( !controlImpl.representsRemoteControl() ) { StatusHolder status = new StatusHolder(); controlImpl.getLocalTID(status); if( status.value != Status.StatusActive ) { // added (Ram J) to handle asynchronous aborts. If a // thread calls commit after an asynchronous abort happens, // end the thread-tx association before throwing // TRANSACTION_ROLLEDBACK exception. // In the case where someone had called terminator.commit // directly successfully, then end the thread association, // before throwing INVALID_TRANSACTION exception. CurrentTransaction.endCurrent(true); if( status.value == Status.StatusRolledBack ) { TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0, CompletionStatus.COMPLETED_NO); throw exc; } INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.Completed, CompletionStatus.COMPLETED_NO); throw exc; } // Check whether there are outstanding requests for this transaction, or // other active threads. active = controlImpl.numAssociated(); } // If this is not the only active thread or there are outstanding requests, // raise an exception and return. if( (active != 1) || (controlImpl.isOutgoing()) ) { /** if( active != 1 ) { } if( controlImpl.isOutgoing() ) { } **/ INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.DeferredActivities, CompletionStatus.COMPLETED_NO); throw exc; } // Get the Terminator from the current Control object. If this fails, then // return whatever exception was raised to the caller. else { Terminator term = null; if (Configuration.isLocalFactory()) { try { term = controlImpl.get_localTerminator(); } catch (Throwable exc) { NO_PERMISSION ex2 = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO); throw ex2; } } else { try { term = controlImpl.get_terminator(); } catch( Throwable exc ) { NO_PERMISSION ex2 = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO); throw ex2; } // Tell the Terminator to commit the transaction. // This will end the current association of the transaction, if the // Terminator is local. If the Terminator is remote, we end the association // ourselves, and do not request unstacking as there will be no stacked // Control. // End the association if the Terminator is remote. This is done under a // local environment to ignore any exception. This must be done before // the Terminator is called otherwise the ControlImpl object will get // confused. try { if( Configuration.getProxyChecker().isProxy(term) ) { CurrentTransaction.endCurrent(true); } } catch( Throwable exc ) {} } // Commit the transaction. try{ term.commit(reportHeuristics); } catch (TRANSACTION_ROLLEDBACK e) { // ADDED (Ram J) (10/15/01) To handle asynchronous aborts. End // thread-tx association before re-throwing exception. This is // because commit/rollback operation by a different thread // does not set all other thread's control's status to INACTIVE // anymore, for performance purposes. CurrentTransaction.endCurrent(true); throw e; } // Free the ControlImpl object. controlImpl.destroy(); } } /**Rolls back the changes performed under the current transaction. *

* This operation can only be called if there is a Terminator object available. * * @param * * @return * * @exception NoTransaction There is no current transaction to rollback. * @exception INVALID_TRANSACTION The current transaction has outstanding * work and the Transaction Service is "checked". * @exception NO_PERMISSION The caller is not allowed to roll the * transaction back. * @exception TRANSACTION_ROLLEDBACK The transaction has already been rolled * back. * @exception SystemException The operation failed. * * @see */ @Override public void rollback() throws NoTransaction, INVALID_TRANSACTION, NO_PERMISSION, TRANSACTION_ROLLEDBACK, SystemException { ControlImpl controlImpl = CurrentTransaction.getCurrent(); if( controlImpl == null ) { NoTransaction exc = new NoTransaction(); throw exc; } // Get the local identifier from the Control object. Raise an exception if // the transaction the Control represents has been completed. int active = 1; if( !controlImpl.representsRemoteControl() ) { StatusHolder status = new StatusHolder(); controlImpl.getLocalTID(status); if( status.value != Status.StatusActive ) { // added (Ram J) to handle asynchronous aborts. If a // thread calls rollback after an asynchronous abort happens, // end the thread-tx association before throwing // TRANSACTION_ROLLEDBACK exception. // In the case where someone had called terminator.commit // directly successfully, then end the thread association, // before throwing INVALID_TRANSACTION exception. CurrentTransaction.endCurrent(true); if( status.value == Status.StatusRolledBack ) { /* TN - do not throw rollback exception TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO); throw exc; */ return; } INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.Completed, CompletionStatus.COMPLETED_NO); throw exc; } // Check whether there are outstanding requests for this transaction, or // other active threads. active = controlImpl.numAssociated(); } // If this is not the only active thread or there are outstanding requests, // raise an exception and return. if( (active != 1) || (controlImpl.isOutgoing()) ) { /** if( active != 1 ) { } if( controlImpl.isOutgoing() ) { } **/ INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.DeferredActivities, CompletionStatus.COMPLETED_NO); throw exc; } // Get the Terminator from the current Control object. If this fails, then // return whatever exception was raised to the caller. else { Terminator term = null; if (Configuration.isLocalFactory()) { try { term = controlImpl.get_localTerminator(); } catch( Unavailable exc ) { NO_PERMISSION ex2 = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO); throw ex2; } } else { try { term = controlImpl.get_terminator(); } catch( Unavailable exc ) { NO_PERMISSION ex2 = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO); throw ex2; } // Tell the Terminator to roll the transaction back. // This will end the current association of the transaction, if the // Terminator is local. If the Terminator is remote, we end the association // ourselves, and do not request unstacking as there will be no stacked // Control. // End the association if the Terminator is remote. This is done under a // local environment to ignore any exception. This must be done before // the Terminator is called otherwise the ControlImpl object will get // confused. try { if( Configuration.getProxyChecker().isProxy(term) ) { CurrentTransaction.endCurrent(true); } } catch( Throwable exc ) {} } // Roll the transaction back. try{ term.rollback(); } catch (TRANSACTION_ROLLEDBACK e) { // ADDED (Ram J) (10/15/01) To handle asynchronous aborts. End // thread-tx association before re-throwing exception. This is // because commit/rollback operation by a different thread // does not set all other thread's control's status to INACTIVE // anymore, for performance purposes. CurrentTransaction.endCurrent(true); //throw e; // no need to throw this for rollback operation. } // Free the ControlImpl object. controlImpl.destroy(); } } /**Marks the current transaction such that is cannot be committed and only * rolled back. * * @param * * @return * * @exception NoTransaction There is no current transaction to mark rollback- * only. * * @see */ @Override public void rollback_only() throws NoTransaction { // Get the reference of the current Coordinator. If there is none, raise the // NoTransaction exception. try { Coordinator coord = CurrentTransaction.getCurrentCoordinator(); // Tell the Coordinator to mark itself rollback-only. coord.rollback_only(); } catch( Throwable exc ) { throw new NoTransaction(); } } /**Returns the status of the current transaction. * * @param * * @return The current status of the transaction. If there is no * current transaction, the value StatusNoTransaction is returned. * * @see */ @Override public Status get_status() { Status result = Status.StatusNoTransaction; try { Coordinator coord = CurrentTransaction.getCurrentCoordinator(); // Ask the Coordinator object for its status, and return the value. if( coord != null ) { result = coord.get_status(); } } catch( Unavailable exc ) { } catch( TRANSACTION_ROLLEDBACK exc ) { result = Status.StatusRolledBack; } catch( SystemException exc ) { result = Status.StatusUnknown; } return result; } /**Returns a printable string representing the current transaction. * * @param * * @return The transaction name. If there is no current transaction, * null is returned. * * @see */ @Override public String get_transaction_name() { String result = null; try { Coordinator coord = CurrentTransaction.getCurrentCoordinator(); // Ask the Coordinator object for its name, and return the value. if( coord != null ) { result = coord.get_transaction_name(); } } // Ignore Unavailable (return null in this case), but allow other exceptions // to percolate up. catch( Unavailable exc ) {} return result; } /**Sets the timeout value to be used for all subsequent transactions. * * @param timeout The timeout value in seconds. * * @return * * @see */ @Override public void set_timeout( int timeout ) { // timeout < 0 will be rejected (no op). // timeout = 0 implies tx has no timeout or a default timeout is used. // timeout > 0 implies tx will timeout at the end of the duration. if (timeout >= 0) { timeOut = timeout; } } @Override public int get_timeout() { return timeOut; } /**Returns the current ControlImpl object. * * @param * * @return The Control object for the current transaction, or null * if there is no current transaction. * * @exception TRANSACTION_ROLLEDBACK The current transaction has been rolled * back. * * @see */ @Override public Control get_control() throws TRANSACTION_ROLLEDBACK { Control result = null; // Get the current Control reference from the TransactionManager. If there // is none, return a NULL pointer. // If the current Control object indicates that the transaction has ended, // then the current association will be ended and the TRANSACTION_ROLLEDBACK // exception will be raised. ControlImpl control = CurrentTransaction.getCurrent(); if (control != null) { if (Configuration.isLocalFactory()) { result = control; } else { result = control.object(); } } return result; } /**Disassociates the current ControlImpl from the calling thread. * * @param * * @return The Control object for the suspended transaction. If * there was no transaction, this will be null. * * @see */ @Override public Control suspend() { Control result = null; ControlImpl cImpl = CurrentTransaction.endCurrent(false); if(_logger.isLoggable(Level.FINEST)) { _logger.logp(Level.FINEST,"CurrentImpl","suspend()", "Current thread has been disassociated from control :" +cImpl); } if (Configuration.isLocalFactory()) { result = cImpl; } else { if (cImpl != null) { result = cImpl.object(); } } return result; } /**Re-associates the given Control to the calling thread. *

* If there is already a current ControlImpl, it is replaced as the current one. * * @param control The Control object to be made current. * * @return * * @exception InvalidControl The Control object passed as a parameter is * not valid. This may be because the transaction it represents has * already completed, or because the object is of the wrong type. * @exception INVALID_TRANSACTION The transaction could not be begun as the * current thread of control has pending non-transactional work. * * @see */ @Override public void resume( Control control ) throws InvalidControl, INVALID_TRANSACTION { ControlImpl contImpl = null; // If the Control object is NULL, then this operation is actually a suspend // operation, so end the current association with the thread. if( control == null ) { CurrentTransaction.endCurrent(false); } else { if (Configuration.isLocalFactory()) { contImpl = (ControlImpl) control; } else { // Check the ControlImpl object is valid. JControl jcontrol = JControlHelper.narrow(control); // Try to locate the local ControlImpl object for the transaction. if( jcontrol != null ) { contImpl = ControlImpl.servant(jcontrol); } // If there is no local ControlImpl object for the transaction, we create one // now. if( contImpl == null ) { try { contImpl = new ControlImpl(control); } catch( Exception exc ) { InvalidControl ex2 = new InvalidControl(); throw ex2; } } } // End the current association regardless of whether there is one. // Attempt to make the given ControlImpl object the current one. try { CurrentTransaction.endCurrent(false); CurrentTransaction.setCurrent(contImpl,false); if(_logger.isLoggable(Level.FINEST)) { _logger.logp(Level.FINEST,"CurrentImpl","resume(control)", "Current thread has been associated with control :" +contImpl); } } // The INVALID_TRANSACTION exception at this point indicates that the transaction // may not be resumed. catch( INVALID_TRANSACTION exc ) { throw (INVALID_TRANSACTION)exc.fillInStackTrace(); } } } /**Shuts down all services. * * @param immediate Indicates whether to ignore running transactions. * * @return * * @see */ synchronized void shutdown( boolean immediate ) { // Inform the basic transaction services to shutdown. CurrentTransaction.shutdown(immediate); } /**Prevents any further transactional activity in the process. * * @param * * @return * * @see */ static void deactivate() { active = false; } // // Provide a dummy routine to satisfy the abstract method inherited from org.omg.CosTransactions.Current // public String[] _ids() { return null; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy