Example #1
0
    internal OletxEnlistment(
        bool canDoSinglePhase,
        IEnlistmentNotificationInternal enlistmentNotification,
        Guid transactionGuid,
        EnlistmentOptions enlistmentOptions,
        OletxResourceManager oletxResourceManager,
        OletxTransaction oletxTransaction)
        : base(oletxResourceManager, oletxTransaction)
    {
        // This will get set later by the creator of this object after it
        // has enlisted with the proxy.
        EnlistmentShim = null;
        _phase0Shim    = null;

        _canDoSinglePhase        = canDoSinglePhase;
        _iEnlistmentNotification = enlistmentNotification;
        State            = OletxEnlistmentState.Active;
        _transactionGuid = transactionGuid;

        _proxyPrepareInfoByteArray = null;

        TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

        if (etwLog.IsEnabled())
        {
            etwLog.EnlistmentCreated(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, EnlistmentType.Durable, enlistmentOptions);
        }

        // Always do this last in case anything earlier fails.
        AddToEnlistmentTable();
    }
Example #2
0
    internal OletxEnlistment(
        IEnlistmentNotificationInternal enlistmentNotification,
        OletxTransactionStatus xactStatus,
        byte[] prepareInfoByteArray,
        OletxResourceManager oletxResourceManager)
        : base(oletxResourceManager, null)
    {
        // This will get set later by the creator of this object after it
        // has enlisted with the proxy.
        EnlistmentShim = null;
        _phase0Shim    = null;

        _canDoSinglePhase        = false;
        _iEnlistmentNotification = enlistmentNotification;
        State = OletxEnlistmentState.Active;

        // Do this before we do any tracing because it will affect the trace identifiers that we generate.
        Debug.Assert(prepareInfoByteArray != null,
                     "OletxEnlistment.ctor - null oletxTransaction without a prepareInfoByteArray");

        int prepareInfoLength = prepareInfoByteArray.Length;

        _proxyPrepareInfoByteArray = new byte[prepareInfoLength];
        Array.Copy(prepareInfoByteArray, _proxyPrepareInfoByteArray, prepareInfoLength);

        byte[] txGuidByteArray = new byte[16];
        Array.Copy(_proxyPrepareInfoByteArray, txGuidByteArray, 16);

        _transactionGuid      = new Guid(txGuidByteArray);
        TransactionGuidString = _transactionGuid.ToString();

        TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

        // If this is being created as part of a Reenlist and we already know the
        // outcome, then tell the application.
        switch (xactStatus)
        {
        case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED:
        {
            State = OletxEnlistmentState.Aborting;
            if (etwLog.IsEnabled())
            {
                etwLog.EnlistmentStatus(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, NotificationCall.Rollback);
            }

            _iEnlistmentNotification.Rollback(this);
            break;
        }

        case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
        {
            State = OletxEnlistmentState.Committing;
            // We are going to send the notification to the RM.  We need to put the
            // enlistment on the reenlistPendingList.  We lock the reenlistList because
            // we have decided that is the lock that protects both lists.  The entry will
            // be taken off the reenlistPendingList when the enlistment has
            // EnlistmentDone called on it.  The enlistment will call
            // RemoveFromReenlistPending.
            lock (oletxResourceManager.ReenlistList)
            {
                oletxResourceManager.ReenlistPendingList.Add(this);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.EnlistmentStatus(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, NotificationCall.Commit);
            }

            _iEnlistmentNotification.Commit(this);
            break;
        }

        case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED:
        {
            State = OletxEnlistmentState.Prepared;
            lock (oletxResourceManager.ReenlistList)
            {
                oletxResourceManager.ReenlistList.Add(this);
                oletxResourceManager.StartReenlistThread();
            }
            break;
        }

        default:
        {
            if (etwLog.IsEnabled())
            {
                etwLog.InternalError(SR.OletxEnlistmentUnexpectedTransactionStatus);
            }

            throw TransactionException.Create(
                      SR.OletxEnlistmentUnexpectedTransactionStatus, null, DistributedTxId);
        }
        }

        if (etwLog.IsEnabled())
        {
            etwLog.EnlistmentCreated(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None);
        }

        // Always do this last in case anything prior to this fails.
        AddToEnlistmentTable();
    }