internal static byte[] GetTransmitterPropagationToken( OletxTransaction oletxTx ) { byte[] propagationToken = null; CoTaskMemHandle propagationTokenBuffer = null; UInt32 tokenSize = 0; try { oletxTx.realOletxTransaction.TransactionShim.GetPropagationToken( out tokenSize, out propagationTokenBuffer); propagationToken = new byte[tokenSize]; Marshal.Copy(propagationTokenBuffer.DangerousGetHandle(), propagationToken, 0, Convert.ToInt32(tokenSize)); } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); throw; } finally { if (null != propagationTokenBuffer) { propagationTokenBuffer.Close(); } } return(propagationToken); }
public static byte[] GetTransmitterPropagationToken( Transaction transaction ) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } if (null == transaction) { throw new ArgumentNullException("transaction"); } if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransmitterPropagationToken" ); } // First, make sure we are working with an OletxTransaction. OletxTransaction oletxTx = TransactionInterop.ConvertToOletxTransaction(transaction); byte[] token = GetTransmitterPropagationToken(oletxTx); if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransmitterPropagationToken" ); } return(token); }
internal static OletxTransaction ConvertToOletxTransaction( Transaction transaction ) { if (null == transaction) { throw new ArgumentNullException("transaction"); } if (transaction.Disposed) { throw new ObjectDisposedException("Transaction"); } if (transaction.complete) { throw TransactionException.CreateTransactionCompletedException(SR.GetString(SR.TraceSourceLtm), transaction.DistributedTxId); } OletxTransaction oletxTx = transaction.Promote(); System.Diagnostics.Debug.Assert(oletxTx != null, "transaction.Promote returned null instead of throwing."); return(oletxTx); }
internal OletxTransaction PSPEPromote(InternalTransaction tx) { TransactionState state = tx.State; base.CommonEnterState(tx); OletxTransaction oletxTransactionFromTransmitterPropigationToken = null; try { byte[] propagationToken = tx.promoter.Promote(); if (propagationToken == null) { throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("PromotedReturnedInvalidValue"), null); } try { oletxTransactionFromTransmitterPropigationToken = TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(propagationToken); } catch (ArgumentException exception) { throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("PromotedReturnedInvalidValue"), exception); } if (TransactionManager.FindPromotedTransaction(oletxTransactionFromTransmitterPropigationToken.Identifier) != null) { oletxTransactionFromTransmitterPropigationToken.Dispose(); throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("PromotedTransactionExists"), null); } } finally { state.CommonEnterState(tx); } return(oletxTransactionFromTransmitterPropigationToken); }
public static IDtcTransaction GetDtcTransaction(Transaction transaction) { ArgumentNullException.ThrowIfNull(transaction); TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetDtcTransaction)}"); } IDtcTransaction?transactionNative; // First, make sure we are working with an OletxTransaction. OletxTransaction oletxTx = ConvertToOletxTransaction(transaction); try { oletxTx.RealOletxTransaction.TransactionShim.GetITransactionNative(out transactionNative); } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); throw; } if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetDtcTransaction)}"); } return(transactionNative); }
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 static byte[] GetTransmitterPropagationToken(OletxTransaction oletxTx) { CoTaskMemHandle propgationToken = null; byte[] destination = null; uint propagationTokeSize = 0; try { oletxTx.realOletxTransaction.TransactionShim.GetPropagationToken(out propagationTokeSize, out propgationToken); destination = new byte[propagationTokeSize]; Marshal.Copy(propgationToken.DangerousGetHandle(), destination, 0, Convert.ToInt32(propagationTokeSize)); } catch (COMException exception) { OletxTransactionManager.ProxyException(exception); throw; } finally { if (propgationToken != null) { propgationToken.Close(); } } return(destination); }
public static byte[] GetExportCookie(Transaction transaction, byte[] whereabouts) { ArgumentNullException.ThrowIfNull(transaction); ArgumentNullException.ThrowIfNull(whereabouts); TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetExportCookie"); } // Copy the whereabouts so that it cannot be modified later. var whereaboutsCopy = new byte[whereabouts.Length]; Buffer.BlockCopy(whereabouts, 0, whereaboutsCopy, 0, whereabouts.Length); ConvertToOletxTransaction(transaction); byte[] cookie = OletxTransaction.GetExportCookie(whereaboutsCopy); if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetExportCookie"); } return(cookie); }
public static IDtcTransaction GetDtcTransaction(Transaction transaction) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } if (null == transaction) { throw new ArgumentNullException("transaction"); } if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetDtcTransaction"); } IDtcTransaction transactionNative = null; OletxTransaction transaction2 = ConvertToOletxTransaction(transaction); try { transaction2.realOletxTransaction.TransactionShim.GetITransactionNative(out transactionNative); } catch (COMException exception) { OletxTransactionManager.ProxyException(exception); throw; } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetDtcTransaction"); } return(transactionNative); }
public static Transaction GetTransactionFromExportCookie(byte[] cookie) { ArgumentNullException.ThrowIfNull(cookie); if (cookie.Length < 32) { throw new ArgumentException(SR.InvalidArgument, nameof(cookie)); } TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromExportCookie"); } var cookieCopy = new byte[cookie.Length]; Buffer.BlockCopy(cookie, 0, cookieCopy, 0, cookie.Length); cookie = cookieCopy; // Extract the transaction guid from the propagation token to see if we already have a // transaction object for the transaction. // In a cookie, the transaction guid is preceded by a signature guid. var txId = new Guid(cookie.AsSpan(16, 16)); // First check to see if there is a promoted LTM transaction with the same ID. If there // is, just return that. Transaction?transaction = TransactionManager.FindPromotedTransaction(txId); if (transaction != null) { if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromExportCookie"); } return(transaction); } // Find or create the promoted transaction. OletxTransaction dTx = OletxTransactionManager.GetTransactionFromExportCookie(cookieCopy, txId); transaction = TransactionManager.FindOrCreatePromotedTransaction(txId, dTx); if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromExportCookie"); } return(transaction); }
internal InternalTransaction(Transaction outcomeSource, OletxTransaction distributedTx) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } this.promotedTransaction = distributedTx; this.absoluteTimeout = 0x7fffffffffffffffL; this.outcomeSource = outcomeSource; this.transactionHash = TransactionManager.TransactionTable.Add(this); TransactionState._TransactionStateNonCommittablePromoted.EnterState(this); this.promoteState = TransactionState._TransactionStateNonCommittablePromoted; }
public static byte[] GetExportCookie(Transaction transaction, byte[] whereabouts) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } byte[] destination = null; if (null == transaction) { throw new ArgumentNullException("transaction"); } if (whereabouts == null) { throw new ArgumentNullException("whereabouts"); } if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetExportCookie"); } byte[] destinationArray = new byte[whereabouts.Length]; Array.Copy(whereabouts, destinationArray, whereabouts.Length); whereabouts = destinationArray; int cookieIndex = 0; uint cookieSize = 0; CoTaskMemHandle cookieBuffer = null; OletxTransaction transaction2 = ConvertToOletxTransaction(transaction); try { transaction2.realOletxTransaction.TransactionShim.Export(Convert.ToUInt32(whereabouts.Length), whereabouts, out cookieIndex, out cookieSize, out cookieBuffer); destination = new byte[cookieSize]; Marshal.Copy(cookieBuffer.DangerousGetHandle(), destination, 0, Convert.ToInt32(cookieSize)); } catch (COMException exception) { OletxTransactionManager.ProxyException(exception); throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } finally { if (cookieBuffer != null) { cookieBuffer.Close(); } } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetExportCookie"); } return(destination); }
internal override void EnterState(InternalTransaction tx) { if (tx.outcomeSource.isoLevel == IsolationLevel.Snapshot) { throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("CannotPromoteSnapshot"), null); } base.CommonEnterState(tx); OletxTransaction transaction = null; try { if (DiagnosticTrace.Verbose && (tx.durableEnlistment != null)) { EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), tx.durableEnlistment.EnlistmentTraceId, NotificationCall.Promote); } transaction = TransactionState._TransactionStatePSPEOperation.PSPEPromote(tx); } catch (TransactionPromotionException exception) { tx.innerException = exception; if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), exception); } } finally { if (transaction == null) { tx.State.ChangeStateAbortedDuringPromotion(tx); } } if (transaction != null) { tx.PromotedTransaction = transaction; Hashtable promotedTransactionTable = TransactionManager.PromotedTransactionTable; lock (promotedTransactionTable) { tx.finalizedObject = new FinalizedObject(tx, tx.PromotedTransaction.Identifier); WeakReference reference = new WeakReference(tx.outcomeSource, false); promotedTransactionTable[tx.PromotedTransaction.Identifier] = reference; } TransactionManager.FireDistributedTransactionStarted(tx.outcomeSource); if (DiagnosticTrace.Information) { TransactionPromotedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), tx.TransactionTraceId, transaction.TransactionTraceId); } this.PromoteEnlistmentsAndOutcome(tx); } }
internal static byte[] GetTransmitterPropagationToken(OletxTransaction oletxTx) { byte[]? propagationToken = null; try { propagationToken = oletxTx.RealOletxTransaction.TransactionShim.GetPropagationToken(); } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); throw; } return(propagationToken); }
public static byte[] GetExportCookie(Transaction transaction, byte[] whereabouts) { ArgumentNullException.ThrowIfNull(transaction); ArgumentNullException.ThrowIfNull(whereabouts); TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetExportCookie)}"); } byte[] cookie; // Copy the whereabouts so that it cannot be modified later. var whereaboutsCopy = new byte[whereabouts.Length]; Buffer.BlockCopy(whereabouts, 0, whereaboutsCopy, 0, whereabouts.Length); // First, make sure we are working with an OletxTransaction. OletxTransaction oletxTx = ConvertToOletxTransaction(transaction); try { oletxTx.RealOletxTransaction.TransactionShim.Export(whereabouts, out cookie); } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); // We are unsure of what the exception may mean. It is possible that // we could get E_FAIL when trying to contact a transaction manager that is // being blocked by a fire wall. On the other hand we may get a COMException // based on bad data. The more common situation is that the data is fine // (since it is generated by Microsoft code) and the problem is with // communication. So in this case we default for unknown exceptions to // assume that the problem is with communication. throw TransactionManagerCommunicationException.Create(null, comException); } if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetExportCookie)}"); } return(cookie); }
public static Transaction GetTransactionFromTransmitterPropagationToken(byte[] propagationToken) { ArgumentNullException.ThrowIfNull(propagationToken); if (propagationToken.Length < 24) { throw new ArgumentException(SR.InvalidArgument, nameof(propagationToken)); } TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromTransmitterPropagationToken"); } // Extract the transaction guid from the propagation token to see if we already have a // transaction object for the transaction. // In a propagation token, the transaction guid is preceded by two version DWORDs. var txId = new Guid(propagationToken.AsSpan(8, 16)); // First check to see if there is a promoted LTM transaction with the same ID. If there is, just return that. Transaction?tx = TransactionManager.FindPromotedTransaction(txId); if (null != tx) { if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromTransmitterPropagationToken"); } return(tx); } OletxTransaction dTx = GetOletxTransactionFromTransmitterPropagationToken(propagationToken); // If a transaction is found then FindOrCreate will Dispose the distributed transaction created. Transaction returnValue = TransactionManager.FindOrCreatePromotedTransaction(txId, dTx); if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromTransmitterPropagationToken"); } return(returnValue); }
public static Transaction GetTransactionFromTransmitterPropagationToken(byte[] propagationToken) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } Transaction transaction2 = null; if (propagationToken == null) { throw new ArgumentNullException("propagationToken"); } if (propagationToken.Length < 0x18) { throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "propagationToken"); } if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromTransmitterPropagationToken"); } byte[] b = new byte[0x10]; for (int i = 0; i < b.Length; i++) { b[i] = propagationToken[i + 8]; } Guid transactionIdentifier = new Guid(b); Transaction transaction = TransactionManager.FindPromotedTransaction(transactionIdentifier); if (null != transaction) { if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromTransmitterPropagationToken"); } return(transaction); } OletxTransaction oletxTransactionFromTransmitterPropigationToken = GetOletxTransactionFromTransmitterPropigationToken(propagationToken); transaction2 = TransactionManager.FindOrCreatePromotedTransaction(transactionIdentifier, oletxTransactionFromTransmitterPropigationToken); if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromTransmitterPropagationToken"); } return(transaction2); }
public static IDtcTransaction GetDtcTransaction( Transaction transaction ) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } if (null == transaction) { throw new ArgumentNullException("transaction"); } if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetDtcTransaction" ); } IDtcTransaction transactionNative = null; // First, make sure we are working with an OletxTransaction. OletxTransaction oletxTx = TransactionInterop.ConvertToOletxTransaction(transaction); try { oletxTx.realOletxTransaction.TransactionShim.GetITransactionNative(out transactionNative); } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); throw; } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetDtcTransaction" ); } return(transactionNative); }
internal static OletxTransaction ConvertToOletxTransaction(Transaction transaction) { ArgumentNullException.ThrowIfNull(transaction); ObjectDisposedException.ThrowIf(transaction.Disposed, transaction); if (transaction._complete) { throw TransactionException.CreateTransactionCompletedException(transaction.DistributedTxId); } OletxTransaction?distributedTx = transaction.Promote(); if (distributedTx == null) { throw OletxTransaction.NotSupported(); } return(distributedTx); }
public static byte[] GetTransmitterPropagationToken(Transaction transaction) { ArgumentNullException.ThrowIfNull(transaction); TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransmitterPropagationToken"); } ConvertToOletxTransaction(transaction); byte[] token = OletxTransaction.GetTransmitterPropagationToken(); if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransmitterPropagationToken"); } return(token); }
public static IDtcTransaction GetDtcTransaction(Transaction transaction) { ArgumentNullException.ThrowIfNull(transaction); TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetDtcTransaction"); } ConvertToOletxTransaction(transaction); IDtcTransaction transactionNative = OletxTransaction.GetDtcTransaction(); if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetDtcTransaction"); } return(transactionNative); }
public static byte[] GetTransmitterPropagationToken(Transaction transaction) { ArgumentNullException.ThrowIfNull(transaction); TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransmitterPropagationToken)}"); } // First, make sure we are working with an OletxTransaction. OletxTransaction oletxTx = ConvertToOletxTransaction(transaction); byte[] token = GetTransmitterPropagationToken(oletxTx); if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransmitterPropagationToken)}"); } return(token); }
public static Transaction GetTransactionFromDtcTransaction(IDtcTransaction transactionNative) { ArgumentNullException.ThrowIfNull(transactionNative, nameof(transactionNative)); TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransactionFromDtcTransaction)}"); } Transaction? transaction = null; bool tooLate = false; TransactionShim?transactionShim = null; Guid txIdentifier = Guid.Empty; OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE; OutcomeEnlistment? outcomeEnlistment = null; RealOletxTransaction?realTx = null; OletxTransaction? oleTx = null; // Let's get the guid of the transaction from the proxy to see if we already have an object. if (transactionNative is not ITransaction myTransactionNative) { throw new ArgumentException(SR.InvalidArgument, nameof(transactionNative)); } OletxXactTransInfo xactInfo; try { myTransactionNative.GetTransactionInfo(out xactInfo); } catch (COMException ex) when(ex.ErrorCode == OletxHelper.XACT_E_NOTRANSACTION) { // If we get here, the transaction has appraently already been committed or aborted. Allow creation of the // OletxTransaction, but it will be marked with a status of InDoubt and attempts to get its Identifier // property will result in a TransactionException. tooLate = true; xactInfo.Uow = Guid.Empty; } OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager; if (!tooLate) { // First check to see if there is a promoted LTM transaction with the same ID. If there // is, just return that. transaction = TransactionManager.FindPromotedTransaction(xactInfo.Uow); if (transaction != null) { if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransactionFromDtcTransaction)}"); } return(transaction); } // We need to create a new RealOletxTransaction... oletxTm.DtcTransactionManagerLock.AcquireReaderLock(-1); try { outcomeEnlistment = new OutcomeEnlistment(); oletxTm.DtcTransactionManager.ProxyShimFactory.CreateTransactionShim( transactionNative, outcomeEnlistment, out txIdentifier, out oletxIsoLevel, out transactionShim); } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); throw; } finally { oletxTm.DtcTransactionManagerLock.ReleaseReaderLock(); } // We need to create a new RealOletxTransaction. realTx = new RealOletxTransaction( oletxTm, transactionShim, outcomeEnlistment, txIdentifier, oletxIsoLevel, false); oleTx = new OletxTransaction(realTx); // If a transaction is found then FindOrCreate will Dispose the oletx // created. transaction = TransactionManager.FindOrCreatePromotedTransaction(xactInfo.Uow, oleTx); } else { // It was too late to do a clone of the provided ITransactionNative, so we are just going to // create a RealOletxTransaction without a transaction shim or outcome enlistment. realTx = new RealOletxTransaction( oletxTm, null, null, txIdentifier, OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE, false); oleTx = new OletxTransaction(realTx); transaction = new Transaction(oleTx); TransactionManager.FireDistributedTransactionStarted(transaction); oleTx.SavedLtmPromotedTransaction = transaction; InternalTransaction.DistributedTransactionOutcome(transaction._internalTransaction, TransactionStatus.InDoubt); } if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransactionFromDtcTransaction)}"); } return(transaction); }
internal static Transaction FindOrCreatePromotedTransaction(Guid transactionIdentifier, OletxTransaction oletx) { Transaction target = null; Hashtable promotedTransactionTable = PromotedTransactionTable; lock (promotedTransactionTable) { WeakReference reference = (WeakReference)promotedTransactionTable[transactionIdentifier]; if (reference != null) { target = reference.Target as Transaction; if (null != target) { oletx.Dispose(); return(target.InternalClone()); } lock (promotedTransactionTable) { promotedTransactionTable.Remove(transactionIdentifier); } } target = new Transaction(oletx) { internalTransaction = { finalizedObject = new FinalizedObject(target.internalTransaction, oletx.Identifier) } }; reference = new WeakReference(target, false); promotedTransactionTable[oletx.Identifier] = reference; } oletx.savedLtmPromotedTransaction = target; FireDistributedTransactionStarted(target); return(target); }
public static byte[] GetExportCookie( Transaction transaction, byte[] whereabouts ) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } byte[] cookie = null; if (null == transaction) { throw new ArgumentNullException("transaction"); } if (null == whereabouts) { throw new ArgumentNullException("whereabouts"); } if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetExportCookie" ); } // Copy the whereabouts so that it cannot be modified later. byte[] whereaboutsCopy = new byte[whereabouts.Length]; Array.Copy(whereabouts, whereaboutsCopy, whereabouts.Length); whereabouts = whereaboutsCopy; int cookieIndex = 0; UInt32 cookieSize = 0; CoTaskMemHandle cookieBuffer = null; // First, make sure we are working with an OletxTransaction. OletxTransaction oletxTx = TransactionInterop.ConvertToOletxTransaction(transaction); try { oletxTx.realOletxTransaction.TransactionShim.Export( Convert.ToUInt32(whereabouts.Length), whereabouts, out cookieIndex, out cookieSize, out cookieBuffer); // allocate and fill in the cookie cookie = new byte[cookieSize]; Marshal.Copy(cookieBuffer.DangerousGetHandle(), cookie, 0, Convert.ToInt32(cookieSize)); } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); // We are unsure of what the exception may mean. It is possible that // we could get E_FAIL when trying to contact a transaction manager that is // being blocked by a fire wall. On the other hand we may get a COMException // based on bad data. The more common situation is that the data is fine // (since it is generated by Microsoft code) and the problem is with // communication. So in this case we default for unknown exceptions to // assume that the problem is with communication. throw TransactionManagerCommunicationException.Create(SR.GetString(SR.TraceSourceOletx), comException); } finally { if (null != cookieBuffer) { cookieBuffer.Close(); } } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetExportCookie" ); } return(cookie); }
public static Transaction GetTransactionFromDtcTransaction( IDtcTransaction transactionNative ) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } bool tooLate = false; ITransactionShim transactionShim = null; Guid txIdentifier = Guid.Empty; OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE; OutcomeEnlistment outcomeEnlistment = null; RealOletxTransaction realTx = null; OletxTransaction oleTx = null; if (null == transactionNative) { throw new ArgumentNullException("transactionNative"); } Transaction transaction = null; if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransactionFromDtc" ); } // Let's get the guid of the transaction from the proxy to see if we already // have an object. ITransactionNativeInternal myTransactionNative = transactionNative as ITransactionNativeInternal; if (null == myTransactionNative) { throw new ArgumentException(SR.GetString(SR.InvalidArgument), "transactionNative"); } OletxXactTransInfo xactInfo; try { myTransactionNative.GetTransactionInfo(out xactInfo); } catch (COMException ex) { if (Oletx.NativeMethods.XACT_E_NOTRANSACTION != ex.ErrorCode) { throw; } // If we get here, the transaction has appraently already been committed or aborted. Allow creation of the // OletxTransaction, but it will be marked with a status of InDoubt and attempts to get its Identifier // property will result in a TransactionException. tooLate = true; xactInfo.uow = Guid.Empty; } OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager; if (!tooLate) { // First check to see if there is a promoted LTM transaction with the same ID. If there // is, just return that. transaction = TransactionManager.FindPromotedTransaction(xactInfo.uow); if (null != transaction) { if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransactionFromDtcTransaction" ); } return(transaction); } // We need to create a new RealOletxTransaction... oletxTm.dtcTransactionManagerLock.AcquireReaderLock(-1); try { outcomeEnlistment = new OutcomeEnlistment(); IntPtr outcomeEnlistmentHandle = IntPtr.Zero; RuntimeHelpers.PrepareConstrainedRegions(); try { outcomeEnlistmentHandle = HandleTable.AllocHandle(outcomeEnlistment); oletxTm.DtcTransactionManager.ProxyShimFactory.CreateTransactionShim( transactionNative, outcomeEnlistmentHandle, out txIdentifier, out oletxIsoLevel, out transactionShim); } finally { if (transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero) { HandleTable.FreeHandle(outcomeEnlistmentHandle); } } } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); throw; } finally { oletxTm.dtcTransactionManagerLock.ReleaseReaderLock(); } // We need to create a new RealOletxTransaction. realTx = new RealOletxTransaction( oletxTm, transactionShim, outcomeEnlistment, txIdentifier, oletxIsoLevel, false); oleTx = new OletxTransaction(realTx); // If a transaction is found then FindOrCreate will Dispose the oletx // created. transaction = TransactionManager.FindOrCreatePromotedTransaction(xactInfo.uow, oleTx); } else { // It was too late to do a clone of the provided ITransactionNative, so we are just going to // create a RealOletxTransaction without a transaction shim or outcome enlistment. realTx = new RealOletxTransaction( oletxTm, null, null, txIdentifier, OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE, false); oleTx = new OletxTransaction(realTx); transaction = new Transaction(oleTx); TransactionManager.FireDistributedTransactionStarted(transaction); oleTx.savedLtmPromotedTransaction = transaction; InternalTransaction.DistributedTransactionOutcome(transaction.internalTransaction, TransactionStatus.InDoubt); } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransactionFromDtc" ); } return(transaction); }
internal Transaction(OletxTransaction oleTransaction) { this.isoLevel = oleTransaction.IsolationLevel; this.internalTransaction = new InternalTransaction(this, oleTransaction); this.cloneId = Interlocked.Increment(ref this.internalTransaction.cloneCount); }
public static Transaction GetTransactionFromTransmitterPropagationToken( byte[] propagationToken ) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } Transaction returnValue = null; if (null == propagationToken) { throw new ArgumentNullException("propagationToken"); } if (propagationToken.Length < 24) { throw new ArgumentException(SR.GetString(SR.InvalidArgument), "propagationToken"); } if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransactionFromTransmitterPropagationToken" ); } // Extract the transaction guid from the propagation token to see if we already have a // transaction object for the transaction. byte[] guidByteArray = new byte[16]; for (int i = 0; i < guidByteArray.Length; i++) { // In a propagation token, the transaction guid is preceeded by two version DWORDs. guidByteArray[i] = propagationToken[i + 8]; } Guid txId = new Guid(guidByteArray); // First check to see if there is a promoted LTM transaction with the same ID. If there // is, just return that. Transaction tx = TransactionManager.FindPromotedTransaction(txId); if (null != tx) { if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransactionFromTransmitterPropagationToken" ); } return(tx); } OletxTransaction oleTx = TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(propagationToken); // If a transaction is found then FindOrCreate will Dispose the oletx // created. returnValue = TransactionManager.FindOrCreatePromotedTransaction(txId, oleTx); if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransactionFromTransmitterPropagationToken" ); } return(returnValue); }
public static Transaction GetTransactionFromExportCookie(byte[] cookie) { ArgumentNullException.ThrowIfNull(cookie); if (cookie.Length < 32) { throw new ArgumentException(SR.InvalidArgument, nameof(cookie)); } TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransactionFromExportCookie)}"); } var cookieCopy = new byte[cookie.Length]; Buffer.BlockCopy(cookie, 0, cookieCopy, 0, cookie.Length); cookie = cookieCopy; Transaction? transaction; TransactionShim?transactionShim = null; Guid txIdentifier = Guid.Empty; OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE; OutcomeEnlistment?outcomeEnlistment; OletxTransaction? oleTx; // Extract the transaction guid from the propagation token to see if we already have a // transaction object for the transaction. // In a cookie, the transaction guid is preceded by a signature guid. var txId = new Guid(cookie.AsSpan(16, 16)); // First check to see if there is a promoted LTM transaction with the same ID. If there // is, just return that. transaction = TransactionManager.FindPromotedTransaction(txId); if (transaction != null) { if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromExportCookie"); } return(transaction); } // We need to create a new transaction RealOletxTransaction? realTx = null; OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager; oletxTm.DtcTransactionManagerLock.AcquireReaderLock(-1); try { outcomeEnlistment = new OutcomeEnlistment(); oletxTm.DtcTransactionManager.ProxyShimFactory.Import(cookie, outcomeEnlistment, out txIdentifier, out oletxIsoLevel, out transactionShim); } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); // We are unsure of what the exception may mean. It is possible that // we could get E_FAIL when trying to contact a transaction manager that is // being blocked by a fire wall. On the other hand we may get a COMException // based on bad data. The more common situation is that the data is fine // (since it is generated by Microsoft code) and the problem is with // communication. So in this case we default for unknown exceptions to // assume that the problem is with communication. throw TransactionManagerCommunicationException.Create(SR.TraceSourceOletx, comException); } finally { oletxTm.DtcTransactionManagerLock.ReleaseReaderLock(); } // We need to create a new RealOletxTransaction. realTx = new RealOletxTransaction( oletxTm, transactionShim, outcomeEnlistment, txIdentifier, oletxIsoLevel, false); // Now create the associated OletxTransaction. oleTx = new OletxTransaction(realTx); // If a transaction is found then FindOrCreate will Dispose the oletx // created. transaction = TransactionManager.FindOrCreatePromotedTransaction(txId, oleTx); if (etwLog.IsEnabled()) { etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransactionFromExportCookie)}"); } return(transaction); }
public static Transaction GetTransactionFromExportCookie( byte[] cookie ) { if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } if (null == cookie) { throw new ArgumentNullException("cookie"); } if (cookie.Length < 32) { throw new ArgumentException(SR.GetString(SR.InvalidArgument), "cookie"); } if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransactionFromExportCookie" ); } byte[] cookieCopy = new byte[cookie.Length]; Array.Copy(cookie, cookieCopy, cookie.Length); cookie = cookieCopy; Transaction transaction = null; ITransactionShim transactionShim = null; Guid txIdentifier = Guid.Empty; OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE; OutcomeEnlistment outcomeEnlistment = null; OletxTransaction oleTx = null; // Extract the transaction guid from the propagation token to see if we already have a // transaction object for the transaction. byte[] guidByteArray = new byte[16]; for (int i = 0; i < guidByteArray.Length; i++) { // In a cookie, the transaction guid is preceeded by a signature guid. guidByteArray[i] = cookie[i + 16]; } Guid txId = new Guid(guidByteArray); // First check to see if there is a promoted LTM transaction with the same ID. If there // is, just return that. transaction = TransactionManager.FindPromotedTransaction(txId); if (null != transaction) { if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransactionFromExportCookie" ); } return(transaction); } // We need to create a new transaction RealOletxTransaction realTx = null; OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager; oletxTm.dtcTransactionManagerLock.AcquireReaderLock(-1); try { outcomeEnlistment = new OutcomeEnlistment(); IntPtr outcomeEnlistmentHandle = IntPtr.Zero; RuntimeHelpers.PrepareConstrainedRegions(); try { outcomeEnlistmentHandle = HandleTable.AllocHandle(outcomeEnlistment); oletxTm.DtcTransactionManager.ProxyShimFactory.Import( Convert.ToUInt32(cookie.Length), cookie, outcomeEnlistmentHandle, out txIdentifier, out oletxIsoLevel, out transactionShim); } finally { if (transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero) { HandleTable.FreeHandle(outcomeEnlistmentHandle); } } } catch (COMException comException) { OletxTransactionManager.ProxyException(comException); // We are unsure of what the exception may mean. It is possible that // we could get E_FAIL when trying to contact a transaction manager that is // being blocked by a fire wall. On the other hand we may get a COMException // based on bad data. The more common situation is that the data is fine // (since it is generated by Microsoft code) and the problem is with // communication. So in this case we default for unknown exceptions to // assume that the problem is with communication. throw TransactionManagerCommunicationException.Create(SR.GetString(SR.TraceSourceOletx), comException); } finally { oletxTm.dtcTransactionManagerLock.ReleaseReaderLock(); } // We need to create a new RealOletxTransaction. realTx = new RealOletxTransaction( oletxTm, transactionShim, outcomeEnlistment, txIdentifier, oletxIsoLevel, false); // Now create the associated OletxTransaction. oleTx = new OletxTransaction(realTx); // If a transaction is found then FindOrCreate will Dispose the oletx // created. transaction = TransactionManager.FindOrCreatePromotedTransaction(txId, oleTx); if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx), "TransactionInterop.GetTransactionFromExportCookie" ); } return(transaction); }