Package com.arjuna.ats.internal.jts.recovery.transactions

Source Code of com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction

/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags.
* See the copyright.txt in the distribution for a full listing
* of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA  02110-1301, USA.
*
* (C) 2005-2006,
* @author JBoss Inc.
*/
/*
* Copyright (C) 2000, 2001,
*
* Arjuna Solutions Limited,
* Newcastle upon Tyne,
* Tyne and Wear,
* UK.
*
* $Id: RecoveredServerTransaction.java 2342 2006-03-30 13:06:17Z  $
*/

package com.arjuna.ats.internal.jts.recovery.transactions;

import com.arjuna.ats.internal.arjuna.Header;
import com.arjuna.ats.internal.jts.Implementations;
import com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.*;
import org.omg.CosTransactions.*;
import java.io.IOException;
import java.util.Date;

import com.arjuna.ats.jts.utils.Utility;

import com.arjuna.ats.internal.jts.orbspecific.interposition.coordinator.ServerTransaction;
import com.arjuna.ats.internal.jts.orbspecific.interposition.*;
import com.arjuna.ats.internal.jts.recovery.contact.StatusChecker;
import com.arjuna.ats.arjuna.exceptions.*;
import com.arjuna.ats.arjuna.common.*;
import com.arjuna.ats.arjuna.coordinator.*;
import com.arjuna.ats.arjuna.objectstore.*;
import com.arjuna.ats.arjuna.state.*;

import com.arjuna.ats.jts.logging.jtsLogger;
import com.arjuna.ats.arjuna.logging.FacilityCode;
import com.arjuna.common.util.logging.*;

import org.omg.CORBA.SystemException;
import org.omg.CORBA.OBJECT_NOT_EXIST;

import org.omg.CORBA.TRANSIENT;

/**
* Transaction type only instantiated at recovery time. This is used to
* re-activate the state of a server transaction that did not terminate
* correctly due to failure.
* <P>
*
* @author Dave Ingham (dave@arjuna.com)
* @version $Id: RecoveredServerTransaction.java 2342 2006-03-30 13:06:17Z $
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_1
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_1] - RecoveredServerTransaction {0}
*          created
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_2
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_2] - RecoveredServerTransaction -
*          activate of {0} failed!
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_4
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_4] -
*          RecoveredServerTransaction.replayPhase2({0}) - status = {1}
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_5
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_5] -
*          RecoveredServerTransaction.replayPhase2({0}) - status after
*          contacting parent = {1}
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_6
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_6] - ServerTransaction {0} unable
*          determine status - retry later
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_7
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_7] -
*          RecoveredServerTransaction.replayPhase2: unexpected Status: {0}
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_8
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_8] -
*          RecoveredServerTransaction.replayPhase2: ({0}) finished
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_9
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_9] -
*          RecoveredServerTransaction.getStatusFromParent - replay_completion
*          status = {0}
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_10
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_10] - Got TRANSIENT from ORB for tx {0}
*          and assuming OBJECT_NOT_EXIST
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_11
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_11] -
*          RecoveredServerTransaction.getStatusFromParent - replay_completion
*          got object_not_exist = {0}
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_12
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_12] - RecoveredServerTransaction: caught
*          NotPrepared
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_13
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_13] - RecoveredServerTransaction: caught
*          unexpected exception:
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_14
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_14] - RecoveredServerTransaction: {0} is
*          invalid
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_15
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_15] -
*          RecoveredServerTransaction:getStatusFromParent - no recovcoord or
*          status not prepared
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_16
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_16] -
*          "RecoveredServerTransaction.unpackHeader - txid = {0} and processUid
*          = {1}
* @message com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_17
*          [com.arjuna.ats.internal.jts.recovery.transactions
*          .RecoveredServerTransaction_17] - RecoveredServerTransaction -
*          activate of {0} failed with {1}
*/

public class RecoveredServerTransaction extends ServerTransaction implements
        RecoveringTransaction
{
    /**
     * actionUid is the local transaction identification for the remote
     * transaction - the name of the store entry which contains the state of the
     * server transaction. The actual main transaction id is only obtained when
     * we activate the transaction.
     */

    public RecoveredServerTransaction(Uid actionUid)
    {
        this(actionUid, "");
    }

    /**
     * actionUid is the local transaction identification for the remote
     * transaction - the name of the store entry which contains the state of the
     * server transaction. The actual main transaction id is only obtained when
     * we activate the transaction.
     */

    public RecoveredServerTransaction(Uid actionUid, String changedTypeName)
    {
        super(actionUid);

        if (jtsLogger.loggerI18N.isDebugEnabled())
        {
            jtsLogger.loggerI18N
                    .debug(
                            DebugLevel.CONSTRUCTORS,
                            VisibilityLevel.VIS_PUBLIC,
                            FacilityCode.FAC_CRASH_RECOVERY,
                            "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_1",
                            new Object[]
                            { getSavingUid() });
        }

        // Don't bother trying to activate a transaction that isn't in
        // the store. This saves an error message.
        _recoveryStatus = RecoveryStatus.ACTIVATE_FAILED;

        String effectiveTypeName = typeName();

        if (changedTypeName.length() < 1)
        {
            _typeName = null;
        }
        else
        {
            _typeName = changedTypeName;
            effectiveTypeName = changedTypeName;
        }

        _originalProcessUid = new Uid(Uid.nullUid());

        try
        {
            if ((store().currentState(getSavingUid(), effectiveTypeName) != ObjectStore.OS_UNKNOWN))
            {
                /*
                 * By activating the state we get the actual transaction id and
                 * process id, which are needed for recovery purposes.
                 */

                if (activate())
                    _recoveryStatus = RecoveryStatus.ACTIVATED;
                else
                {
                    jtsLogger.loggerI18N
                            .warn(
                                    "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_2",
                                    new Object[]
                                    { getSavingUid() });
                }
                ;
            }
        }
        catch (Exception e)
        {
            jtsLogger.loggerI18N
                    .warn(
                            "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_2",
                            new Object[]
                            { getSavingUid(), e });
        }

        _txStatus = Status.StatusUnknown;
    }

    /**
     * Get the status of the transaction. If we successfully activated the
     * transaction then we return whatever the transaction reports otherwise we
     * return RolledBack as we're using presumed abort.
     */
    public synchronized Status get_status () throws SystemException
    {
        if (_txStatus != Status.StatusUnknown)
            return _txStatus;

        Status theStatus = Status.StatusUnknown;

        if (_recoveryStatus == RecoveryStatus.ACTIVATE_FAILED)
            theStatus = Status.StatusRolledBack;
        else
            theStatus = super.get_status();

        return theStatus;
    }

    /**
     * Allows a new Resource to be added to the transaction. Typically this is
     * used to replace a Resource that has failed and cannot be recovered on
     * it's original IOR.
     */
    public void addResourceRecord (Uid rcUid, Resource r)
    {
        Coordinator coord = null;
        AbstractRecord corbaRec = createOTSRecord(true, r, coord, rcUid);

        addRecord(corbaRec);
    }

    /**
     * Causes phase 2 of the commit protocol to be replayed.
     */
    public void replayPhase2 ()
    {
        _recoveryStatus = RecoveryStatus.REPLAYING;

        Status theStatus = get_status();

        if (jtsLogger.loggerI18N.isDebugEnabled())
        {
            jtsLogger.loggerI18N
                    .debug(
                            DebugLevel.FUNCTIONS,
                            VisibilityLevel.VIS_PUBLIC,
                            FacilityCode.FAC_CRASH_RECOVERY,
                            "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_4",
                            new Object[]
                            { get_uid(), Utility.stringStatus(theStatus) });
        }

        if (theStatus == Status.StatusPrepared)
        {
            /*
             * We need to get the status from the our parent transaction in the
             * interposition hierarchy.
             */
            theStatus = getStatusFromParent();

            if (jtsLogger.loggerI18N.isDebugEnabled())
            {
                jtsLogger.loggerI18N
                        .debug(
                                DebugLevel.FUNCTIONS,
                                VisibilityLevel.VIS_PUBLIC,
                                FacilityCode.FAC_CRASH_RECOVERY,
                                "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_5",
                                new Object[]
                                { get_uid(), Utility.stringStatus(theStatus) });
            }
        }

        if ((theStatus == Status.StatusCommitting)
                || (theStatus == Status.StatusCommitted))
        {
            phase2Commit(_reportHeuristics);

            _recoveryStatus = RecoveryStatus.REPLAYED;

            _txStatus = Status.StatusCommitted;
        }
        else if ((theStatus == Status.StatusRolledBack)
                || (theStatus == Status.StatusRollingBack)
                || (theStatus == Status.StatusMarkedRollback)
                || (theStatus == Status.StatusNoTransaction))
        {
            phase2Abort(_reportHeuristics);

            _recoveryStatus = RecoveryStatus.REPLAYED;

            _txStatus = Status.StatusRolledBack;
        }
        else if (theStatus == Status.StatusUnknown)
        {
            if (jtsLogger.loggerI18N.isInfoEnabled())
            {
                jtsLogger.loggerI18N
                        .info(
                                "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_6",
                                new Object[]
                                { get_uid() });
            }
            _recoveryStatus = RecoveryStatus.REPLAY_FAILED;
        }
        else
        {
            jtsLogger.loggerI18N
                    .warn(
                            "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_7",
                            new Object[]
                            { Utility.stringStatus(theStatus) });
            _recoveryStatus = RecoveryStatus.REPLAY_FAILED;
        }

        if (jtsLogger.loggerI18N.isDebugEnabled())
        {
            jtsLogger.loggerI18N
                    .debug(
                            DebugLevel.FUNCTIONS,
                            VisibilityLevel.VIS_PUBLIC,
                            FacilityCode.FAC_CRASH_RECOVERY,
                            "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_8",
                            new Object[]
                            { get_uid() });
        }
    }

    /**
     * Get the status of recovery for this transaction
     */
    public int getRecoveryStatus ()
    {
        return _recoveryStatus;
    }

    /**
     * Check the status of this transaction state, i.e., that represented by
     * get_uid and not getSavingUid
     */

    public Status getOriginalStatus ()
    {
        if (_recoveryStatus != RecoveryStatus.ACTIVATE_FAILED)
        {
            try
            {
                /*
                 * Remember to get the status on the actual global transaction
                 * and not on the local branch, i.e., use get_uid and not
                 * getSavingUid
                 */

                return StatusChecker.get_status(get_uid(), _originalProcessUid);
            }
            catch (Inactive ex)
            {
                // shouldn't happen!!

                return Status.StatusUnknown;
            }
        }
        else
        {
            // if it can't be activated, we cant get the process uid
            return Status.StatusUnknown;
        }

    }

    private Status getStatusFromParent ()
    {
        org.omg.CosTransactions.Status theStatus = org.omg.CosTransactions.Status.StatusUnknown;

        int not_exist_count; // This variable is applied with Orbix

        if ((super._recoveryCoordinator != null)
                && (get_status() == org.omg.CosTransactions.Status.StatusPrepared))
        {
            ServerControl sc = new ServerControl((ServerTransaction) this);
            ServerRecoveryTopLevelAction tla = new ServerRecoveryTopLevelAction(
                    sc);

            if (tla.valid())
            {
                try
                {
                    theStatus = super._recoveryCoordinator
                            .replay_completion(tla.getReference());

                    if (jtsLogger.loggerI18N.isDebugEnabled())
                    {
                        jtsLogger.loggerI18N
                                .debug(
                                        DebugLevel.FUNCTIONS,
                                        VisibilityLevel.VIS_PUBLIC,
                                        FacilityCode.FAC_CRASH_RECOVERY,
                                        "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_9",
                                        new Object[]
                                        { Utility.stringStatus(theStatus) });
                    }
                }

                catch (TRANSIENT ex_trans)
                {
                    // orbix seems to count unreachable as transient, but we no
                    // longer support orbix
                    jtsLogger.loggerI18N
                            .warn(
                                    "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_10",
                                    new Object[]
                                    { get_uid() });
                    theStatus = org.omg.CosTransactions.Status.StatusRolledBack;
                }
                // What here what should be done for Orbix2000
                catch (OBJECT_NOT_EXIST ex)
                {
                    // i believe this state should be notran - ots explicitly
                    // objnotexist is
                    // rollback

                    theStatus = org.omg.CosTransactions.Status.StatusRolledBack;

                    // theStatus =
                    // org.omg.CosTransactions.Status.StatusNoTransaction;

                    if (jtsLogger.loggerI18N.isDebugEnabled())
                    {
                        jtsLogger.loggerI18N
                                .debug(
                                        DebugLevel.FUNCTIONS,
                                        VisibilityLevel.VIS_PUBLIC,
                                        FacilityCode.FAC_CRASH_RECOVERY,
                                        "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_11",
                                        new Object[]
                                        { Utility.stringStatus(theStatus) });
                    }
                }
                catch (NotPrepared ex1)
                {
                    jtsLogger.loggerI18N
                            .warn("com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_12");
                    theStatus = org.omg.CosTransactions.Status.StatusActive;
                }
                catch (Exception e)
                {
                    // Unknown error, so better to do nothing at this stage.
                    jtsLogger.loggerI18N
                            .warn(
                                    "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_13",
                                    e);
                }
            }
            else
            {
                jtsLogger.loggerI18N
                        .warn(
                                "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_14",
                                new Object[]
                                { get_uid() });
            }
            ;

            // Make sure we "delete" these objects when we are finished
            // with them or there will be a memory leak. If they are deleted
            // "early", and the root coordinator needs them then it will find
            // them unavailable, and will have to retry recovery later.

            sc = null;
            tla = null;
        }
        else
        {
            if (jtsLogger.loggerI18N.isDebugEnabled())
            {
                jtsLogger.loggerI18N
                        .debug(
                                DebugLevel.FUNCTIONS,
                                VisibilityLevel.VIS_PUBLIC,
                                FacilityCode.FAC_CRASH_RECOVERY,
                                "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_15");
            }
        }

        return theStatus;
    }

    public boolean allCompleted ()
    {
        // return (boolean) (_recoveryStatus == RecoveryStatus.REPLAYED);

        return false;
    }

    public String type ()
    {
        if (_typeName == null)
        {
            return super.type();
        }
        else
        {
            return _typeName;
        }
    }

    public void removeOldStoreEntry ()
    {
        try
        {
            store().remove_committed(getSavingUid(), super.type());
        }
        catch (ObjectStoreException ex)
        {
            jtsLogger.loggerI18N.warn(
                    "RecoveredServerTransaction.removeOldStoreEntry ", ex);
        }
    }

    public boolean assumeComplete ()
    {
        _typeName = AssumedCompleteServerTransaction.typeName();
        return true;
    }

    /**
     * Override StateManager packHeader so it gets the original processUid, not
     * this process's
     *
     * @since JTS 2.1.
     */

    protected void packHeader (OutputObjectState os, Header hdr)
            throws IOException
    {
        /*
         * If there is a transaction present than pack the process Uid of this
         * JVM and the tx id. Otherwise pack a null Uid.
         */

        super.packHeader(os, new Header(get_uid(), _originalProcessUid));
    }

    /**
     * Override StateManager's unpackHeader to save the processUid of the
     * original process
     *
     * @since JTS 2.1.
     */

    protected void unpackHeader (InputObjectState os, Header hdr)
            throws IOException
    {  
        super.unpackHeader(os, hdr);
       
        super.objectUid = hdr.getTxId();
        _originalProcessUid = hdr.getProcessId();

        if (jtsLogger.loggerI18N.isDebugEnabled())
        {
            jtsLogger.loggerI18N
                    .debug(
                            DebugLevel.FUNCTIONS,
                            VisibilityLevel.VIS_PUBLIC,
                            FacilityCode.FAC_CRASH_RECOVERY,
                            "com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction_16",
                            new Object[]
                            { get_uid(), _originalProcessUid });
        }
    }

    public boolean save_state (OutputObjectState objectState, int ot)
    {
        // do the other stuff
        boolean result = super.save_state(objectState, ot);

        // iff assumed complete, include the time (this should happen only once)
        if (_typeName != null && result)
        {
            Date lastActiveTime = new Date();
            try
            {
                objectState.packLong(lastActiveTime.getTime());
            }
            catch (java.io.IOException ex)
            {
            }
        }
        return result;
    }

    /** do not admit to being inactive */
    public Date getLastActiveTime ()
    {
        return null;
    }

    protected Uid _originalProcessUid;

    private String _typeName;

    private boolean _reportHeuristics = false;

    private int _recoveryStatus = RecoveryStatus.NEW;

    private org.omg.CosTransactions.Status _txStatus;
}
TOP

Related Classes of com.arjuna.ats.internal.jts.recovery.transactions.RecoveredServerTransaction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.