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(); }
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(); }