public ActivityThread(SessionTracker tracker, Amnesia.SessionTracker.ActivityInfo activity, DependentTransaction transaction) { this.tracker = tracker; this.transaction = transaction; tracker.ParallelDependentActivityStarted(activity); }
public DependentTransaction DependentClone(DependentCloneOption cloneOption) { if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), "Transaction.DependentClone"); } if ((cloneOption != DependentCloneOption.BlockCommitUntilComplete) && (cloneOption != DependentCloneOption.RollbackIfNotComplete)) { throw new ArgumentOutOfRangeException("cloneOption"); } if (this.Disposed) { throw new ObjectDisposedException("Transaction"); } if (this.complete) { throw TransactionException.CreateTransactionCompletedException(System.Transactions.SR.GetString("TraceSourceLtm")); } DependentTransaction transaction = new DependentTransaction(this.isoLevel, this.internalTransaction, cloneOption == DependentCloneOption.BlockCommitUntilComplete); if (DiagnosticTrace.Information) { DependentCloneCreatedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), transaction.TransactionTraceId, cloneOption); } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), "Transaction.DependentClone"); } return(transaction); }
private void SetCurrent(Transaction newCurrent) { if (((this.dependentTransaction == null) && (this.committableTransaction == null)) && (newCurrent != null)) { this.dependentTransaction = newCurrent.DependentClone(DependentCloneOption.RollbackIfNotComplete); } switch (this.interopOption) { case EnterpriseServicesInteropOption.None: this.threadContextData.CurrentTransaction = newCurrent; return; case EnterpriseServicesInteropOption.Automatic: Transaction.VerifyEnterpriseServicesOk(); if (!Transaction.UseServiceDomainForCurrent()) { this.threadContextData.CurrentTransaction = newCurrent; return; } this.PushServiceDomain(newCurrent); return; case EnterpriseServicesInteropOption.Full: Transaction.VerifyEnterpriseServicesOk(); this.PushServiceDomain(newCurrent); return; } }
// Create a dependent clone of the transaction that forwards requests to this object. // public DependentTransaction DependentClone( DependentCloneOption cloneOption ) { TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this); } if (cloneOption != DependentCloneOption.BlockCommitUntilComplete && cloneOption != DependentCloneOption.RollbackIfNotComplete) { throw new ArgumentOutOfRangeException(nameof(cloneOption)); } ObjectDisposedException.ThrowIf(Disposed, this); if (_complete) { throw TransactionException.CreateTransactionCompletedException(DistributedTxId); } DependentTransaction clone = new DependentTransaction( _isoLevel, _internalTransaction, cloneOption == DependentCloneOption.BlockCommitUntilComplete); if (etwLog.IsEnabled()) { etwLog.TransactionCloneCreate(clone, "DependentTransaction"); etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this); } return(clone); }
public DependentTransaction DependentClone(DependentCloneOption option) { var d = new DependentTransaction(this, option); this.dependents.Add(d); return(d); }
internal TransactionWaitAsyncResult(Transaction transaction, PersistenceContext persistenceContext, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { bool completeSelf = false; TransactionException exception = null; this.PersistenceContext = persistenceContext; this.thisLock = new object(); if (null != transaction) { // We want an "blocking" dependent transaction because we want to ensure the transaction // does not commit successfully while we are still waiting in the queue for the PC transaction // lock. this.dependentTransaction = transaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete); } else { this.dependentTransaction = null; } // Put a lock around this and Complete() in case the transaction we are queueing up behind // finishes and we end up calling Complete() before we actually finish constructing this // object by creating the DependentClone and setting up the IOThreadTimer. lock (ThisLock) { if (persistenceContext.QueueForTransactionLock(transaction, this)) { // If we were given a transaction in our constructor, we need to // create a volatile enlistment on it and complete the // dependent clone that we created. This will allow the transaction to commit // successfully when the time comes. if (null != transaction) { // We are not going async, so we need to complete our dependent clone now. this.dependentTransaction.Complete(); exception = this.CreateVolatileEnlistment(transaction); } completeSelf = true; } else { // If the timeout value is not TimeSpan.MaxValue, start a timer. if (timeout != TimeSpan.MaxValue) { this.timer = new IOThreadTimer(TimeoutCallbackAction, this, true); this.timer.Set(timeout); } } } // We didn't want to call Complete while holding the lock. if (completeSelf) { base.Complete(true, exception); } }
public DependentTransaction DependentClone( DependentCloneOption cloneOption) { DependentTransaction d = new DependentTransaction(this, cloneOption); dependents.Add(d); return(d); }
public void TrackStoreUnlock(DependentTransaction dependentTransaction) { this.BoundToLock = false; this.IsHandleFreed = true; if (dependentTransaction != null) { dependentTransaction.TransactionCompleted += new TransactionCompletedEventHandler(this.TransactedUnlockCompleted); } }
public SqlCommandAsyncResult(SqlCommand sqlCommand, string connectionString, DependentTransaction dependentTransaction, TimeSpan timeout, int retryCount, int maximumRetries, AsyncCallback callback, object state) : base(callback, state) { long num = Math.Min(timeout.Ticks, MaximumOpenTimeout.Ticks); this.sqlCommand = sqlCommand; this.connectionString = connectionString; this.dependentTransaction = dependentTransaction; this.timeoutHelper = new TimeoutHelper(TimeSpan.FromTicks(num)); this.retryCount = retryCount; this.maximumRetries = maximumRetries; }
public FileTransaction(string name, DependentTransaction inner, uint stackDepth, ITransactionOptions creationOptions, Action onDispose) { Contract.Requires(inner != null); Contract.Requires(creationOptions != null); _Inner = new Transaction(inner, stackDepth, creationOptions, onDispose); _Name = name; InnerBegin(); }
private void CommonInitialize() { this.complete = false; this.dependentTransaction = null; this.disposed = false; this.committableTransaction = null; this.expectedCurrent = null; this.scopeTimer = null; this.scopeThread = Thread.CurrentThread; Transaction.GetCurrentTransactionAndScope(out this.savedCurrent, out this.savedCurrentScope, out this.threadContextData, out this.contextTransaction); }
public static sysTx.TransactionScope Make( sysTx.TransactionScopeOption txScopOption = sysTx.TransactionScopeOption.Required, sysTx.IsolationLevel isoLevel = sysTx.IsolationLevel.ReadCommitted, double timeOutMinutes = 30d, sysTx.DependentTransaction depTx = null) { return(depTx != null? new sysTx.TransactionScope(depTx): new sysTx.TransactionScope(txScopOption, new sysTx.TransactionOptions { IsolationLevel = isoLevel, Timeout = TimeSpan.FromMinutes(timeOutMinutes) })); }
public Transaction(DependentTransaction dependent, uint stackDepth, ITransactionOptions creationOptions, Action onDispose) { Contract.Requires(creationOptions != null); Contract.Requires(dependent != null); Contract.Ensures(_State == TransactionState.Active); Contract.Ensures(((ITransaction)this).State == TransactionState.Active); _Dependent = dependent; _CreationOptions = creationOptions; _OnDispose = onDispose; _State = TransactionState.Active; _LocalIdentifier = dependent.TransactionInformation.LocalIdentifier + ":" + stackDepth; }
public void TrackStoreLock(Guid instanceId, long instanceVersion, DependentTransaction dependentTransaction) { this.BoundToLock = true; this.InstanceId = instanceId; this.InstanceVersion = instanceVersion; if (dependentTransaction != null) { dependentTransaction.TransactionCompleted += new TransactionCompletedEventHandler(this.TransactionCompleted); } else { this.IsSafeToUnlock = true; } }
public FileTransaction(string name, DependentTransaction inner, uint stackDepth, ITransactionOptions creationOptions, Action onDispose, ILogger logger) { Contract.Requires(inner != null); Contract.Requires(creationOptions != null); Contract.Requires(!string.IsNullOrEmpty(name)); Contract.Requires(logger != null); Contract.Ensures(_Name != null); _Inner = new Transaction(inner, stackDepth, creationOptions, onDispose, logger.CreateChildLogger("Transaction")); _Name = name; InnerBegin(); }
private void UpdateInventory(DependentTransaction dt, SalesOrderDetail salesDetail) { try { using (AdventureWorksDataContext dc = new AdventureWorksDataContext()) { using (TransactionScope scope = (dt != null ?new TransactionScope(dt) :new TransactionScope(TransactionScopeOption.Suppress))) { var inventoryRow = (from pi in dc.ProductInventories where pi.ProductID == salesDetail.ProductID && pi.LocationID == 7 //finished goods storage select pi).SingleOrDefault(); if (inventoryRow != null) { inventoryRow.Quantity -= salesDetail.OrderQty; inventoryRow.ModifiedDate = DateTime.Now; Console.WriteLine( "Product {0}: Reduced by {1}", inventoryRow.ProductID, salesDetail.OrderQty); dc.SubmitChanges(); } scope.Complete(); } } } catch (Exception) { throw; } finally { //the ambient transaction will block on complete if (dt != null) { dt.Complete(); dt.Dispose(); } } }
// Create a dependent clone of the transaction that forwards requests to this object. // public DependentTransaction DependentClone( DependentCloneOption cloneOption ) { if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(SR.TraceSourceLtm, "Transaction.DependentClone"); } if (cloneOption != DependentCloneOption.BlockCommitUntilComplete && cloneOption != DependentCloneOption.RollbackIfNotComplete) { throw new ArgumentOutOfRangeException(nameof(cloneOption)); } if (Disposed) { throw new ObjectDisposedException(nameof(Transaction)); } if (_complete) { throw TransactionException.CreateTransactionCompletedException(SR.TraceSourceLtm, DistributedTxId); } DependentTransaction clone = new DependentTransaction( _isoLevel, _internalTransaction, cloneOption == DependentCloneOption.BlockCommitUntilComplete); if (DiagnosticTrace.Information) { DependentCloneCreatedTraceRecord.Trace(SR.TraceSourceLtm, clone.TransactionTraceId, cloneOption); } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.TraceSourceLtm, "Transaction.DependentClone"); } return(clone); }
// SetCurrent // // Place the given value in current by whatever means necessary for interop mode. private void SetCurrent(Transaction newCurrent) { // Keep a dependent clone of current if we don't have one and we are not committable if (_dependentTransaction == null && _committableTransaction == null) { if (newCurrent != null) { _dependentTransaction = newCurrent.DependentClone(DependentCloneOption.RollbackIfNotComplete); } } switch (_interopOption) { case EnterpriseServicesInteropOption.None: _threadContextData.CurrentTransaction = newCurrent; break; case EnterpriseServicesInteropOption.Automatic: EnterpriseServices.VerifyEnterpriseServicesOk(); if (EnterpriseServices.UseServiceDomainForCurrent()) { EnterpriseServices.PushServiceDomain(newCurrent); } else { _threadContextData.CurrentTransaction = newCurrent; } break; case EnterpriseServicesInteropOption.Full: EnterpriseServices.VerifyEnterpriseServicesOk(); EnterpriseServices.PushServiceDomain(newCurrent); break; } }
/// <summary> /// Indicate that sql is transaction if trans parameter is not null /// </summary> /// <param name="trans"></param> public void AddTransaction(Transaction trans) { if (trans != null) DependentTransaction = trans.DependentClone(DependentCloneOption.BlockCommitUntilComplete); }
/// <summary> /// Executes sql /// </summary> /// <param name="connectionString"></param> /// <param name="sql"></param> /// <param name="commandTimeout"></param> /// <param name="dtx"></param> /// <returns></returns> private static Exception ExecuteSql(string connectionString, string sql,IList<SqlParameter> parameters,out string output, int commandTimeout, DependentTransaction dtx) { Exception exception = null; output = string.Empty; try { if (dtx != null) { //if transaction - execute in transaction scope using (TransactionScope scope = new TransactionScope(dtx)) { using (SqlConnection conn = new SqlConnection(connectionString)) { //Make sure transaction is placed in DTC IDtcTransaction t = TransactionInterop.GetDtcTransaction(Transaction.Current); conn.Open(); int retryCount = 120; while (retryCount > 0) { try { //Enlist to transaction. Will retry, because sometimes SQL server //reports that transaction is used by another session. //This happens not very often, but this is a protection conn.EnlistTransaction(TransactionInterop.GetTransactionFromDtcTransaction(t)); break; } catch { retryCount--; if (retryCount == 0) throw; Thread.Sleep(500); } } using (SqlCommand cmd = conn.CreateCommand()) { ExecuteSql(cmd, sql, parameters, out output, commandTimeout); } } //commit if success scope.Complete(); } } else { using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { //if not transactional, then just execute sql ExecuteSql(cmd, sql, parameters, out output, commandTimeout); } } } } catch (Exception ex) { exception = ex; } return exception; }
// Create a dependent clone of the transaction that forwards requests to this object. // /// <include file='doc\Transaction.uex' path='docs/doc[@for="Transaction.Clone"]/*' /> public DependentTransaction DependentClone( DependentCloneOption cloneOption ) { if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceLtm), "Transaction.DependentClone" ); } if (cloneOption != DependentCloneOption.BlockCommitUntilComplete && cloneOption != DependentCloneOption.RollbackIfNotComplete) { throw new ArgumentOutOfRangeException("cloneOption"); } if (Disposed) { throw new ObjectDisposedException("Transaction"); } if (this.complete) { throw TransactionException.CreateTransactionCompletedException(SR.GetString(SR.TraceSourceLtm)); } DependentTransaction clone = new DependentTransaction( this.isoLevel, this.internalTransaction, cloneOption == DependentCloneOption.BlockCommitUntilComplete); if (DiagnosticTrace.Information) { DependentCloneCreatedTraceRecord.Trace(SR.GetString(SR.TraceSourceLtm), clone.TransactionTraceId, cloneOption ); } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceLtm), "Transaction.DependentClone" ); } return clone; }
private void CommonInitialize() { ContextKey = new ContextKey(); _complete = false; _dependentTransaction = null; _disposed = false; _committableTransaction = null; _expectedCurrent = null; _scopeTimer = null; _scopeThread = Thread.CurrentThread; Transaction.GetCurrentTransactionAndScope( AsyncFlowEnabled ? TxLookup.DefaultCallContext : TxLookup.DefaultTLS, out _savedCurrent, out _savedCurrentScope, out _contextTransaction ); // Calling validate here as we need to make sure the existing parent ambient transaction scope is already looked up to see if we have ES interop enabled. ValidateAsyncFlowOptionAndESInteropOption(); }
internal void CreateDependentClone() { if ((this.dependentClone == null) && (this.Clone != null)) { this.dependentClone = this.Clone.DependentClone(DependentCloneOption.BlockCommitUntilComplete); } }
public void Dispose() { if (refDisposeCount > 0) refDisposeCount -= 1; else { transactionScope.Dispose(); transactionScope = null; if (dependentTransaction != null) { dependentTransaction.Dispose(); dependentTransaction = null; } } }
public Transaction(DependentTransaction inner, uint stackDepth, ITransactionOptions creationOptions, Action onDispose) { Contract.Requires(creationOptions != null); Contract.Requires(inner != null); Contract.Ensures(_Inner2 != null); Contract.Ensures(_State == TransactionState.Active); Contract.Ensures(((ITransaction) this).State == TransactionState.Active); _Inner2 = inner; _StackDepth = stackDepth; _CreationOptions = creationOptions; _OnDispose = onDispose; _State = TransactionState.Active; }
public UnloadOrPersistAsyncResult(WorkflowServiceInstance instance, WorkflowServiceInstance.PersistenceOperation operation, bool isWorkflowThread, bool isTry, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.instance = instance; this.timeoutHelper = new TimeoutHelper(timeout); this.operation = operation; this.isWorkflowThread = isWorkflowThread; this.isTry = isTry; this.tryResult = true; this.isUnloaded = (operation == WorkflowServiceInstance.PersistenceOperation.Unload) || (operation == WorkflowServiceInstance.PersistenceOperation.Delete); this.saveStatus = SaveStatus.Locked; this.isCompletionTransactionRequired = ((this.isUnloaded && (instance.Controller.State == WorkflowInstanceState.Complete)) && (instance.creationContext != null)) && instance.creationContext.IsCompletionTransactionRequired; this.isIdlePolicyPersist = isTry && (operation == WorkflowServiceInstance.PersistenceOperation.Save); if (operation == WorkflowServiceInstance.PersistenceOperation.Unload) { this.saveStatus = SaveStatus.Unlocked; } else if (operation == WorkflowServiceInstance.PersistenceOperation.Delete) { this.saveStatus = SaveStatus.Completed; } Transaction current = Transaction.Current; if (current != null) { base.OnCompleting = completeCallback; this.dependentTransaction = current.DependentClone(DependentCloneOption.BlockCommitUntilComplete); } bool flag = true; bool flag2 = false; try { if (this.isWorkflowThread) { flag = this.OpenProvider(); } else { try { flag = this.LockAndPassGuard(); } finally { if (flag) { this.instance.ReleaseLock(ref this.ownsLock, this.isIdlePolicyPersist); } } } flag2 = true; } finally { if (!flag2 && (this.dependentTransaction != null)) { this.dependentTransaction.Complete(); } } if (flag) { base.Complete(true); } }
void CompleteClonedTransaction() { if (this.clonedTransaction != null) { this.clonedTransaction.Complete(); this.clonedTransaction = null; } }
public UnloadOrPersistAsyncResult(WorkflowServiceInstance instance, PersistenceOperation operation, bool isWorkflowThread, bool isTry, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { // The isTry flag is only true when this is an idle policy initiated persist/unload. Fx.Assert((isWorkflowThread && !isTry) || !isWorkflowThread, "Either we're the workflow thread and NOT a try or we're not a workflow thread."); this.instance = instance; this.timeoutHelper = new TimeoutHelper(timeout); this.operation = operation; this.isWorkflowThread = isWorkflowThread; this.isTry = isTry; this.tryResult = true; this.isUnloaded = (operation == PersistenceOperation.Unload || operation == PersistenceOperation.Delete); this.saveStatus = SaveStatus.Locked; this.isCompletionTransactionRequired = this.isUnloaded && instance.Controller.State == WorkflowInstanceState.Complete && instance.creationContext != null && instance.creationContext.IsCompletionTransactionRequired; this.isIdlePolicyPersist = isTry && operation == PersistenceOperation.Save; if (operation == PersistenceOperation.Unload) { this.saveStatus = SaveStatus.Unlocked; } else if (operation == PersistenceOperation.Delete) { this.saveStatus = SaveStatus.Completed; } else if (operation == PersistenceOperation.Save) { SetStartTime(); } // Save off the current transaction in case we have an async operation before we end up creating // the WorkflowPersistenceContext and create it on another thread. Do a simple clone here to prevent // the object referenced by Transaction.Current from disposing before we get around to referencing it // when we create the WorkflowPersistenceContext. // // This will throw TransactionAbortedException by design, if the transaction is already rolled back. Transaction currentTransaction = Transaction.Current; if (currentTransaction != null) { OnCompleting = UnloadOrPersistAsyncResult.completeCallback; this.dependentTransaction = currentTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete); } bool completeSelf = true; bool success = false; try { if (this.isWorkflowThread) { Fx.Assert(this.instance.Controller.IsPersistable, "The runtime won't schedule this work item unless we've passed the guard"); // We're an internal persistence on the workflow thread which means // that we are passed the guard already, we have the lock, and we know // we aren't detached. completeSelf = OpenProvider(); } else { try { completeSelf = LockAndPassGuard(); } finally { if (completeSelf) { Fx.Assert(!this.isWorkflowThread, "We should never be calling ReleaseLock if this is the workflow thread."); this.instance.ReleaseLock(ref this.ownsLock, this.isIdlePolicyPersist && this.tryResult); } } } success = true; } finally { if (!success) { if (this.dependentTransaction != null) { this.dependentTransaction.Complete(); } } } if (completeSelf) { Complete(true); } }
public PersistenceScope(bool saveStateInOperationTransaction, DependentTransaction clonedTransaction) { if (!saveStateInOperationTransaction) { this.scope = new TransactionScope(TransactionScopeOption.Suppress); } else if (clonedTransaction != null) { this.clonedTransaction = clonedTransaction; this.scope = new TransactionScope(clonedTransaction); } }
GetInstanceAsyncResult(DurableInstanceManager instanceManager, WorkflowGetInstanceContext parameters, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.instanceManager = instanceManager; this.parameters = parameters; this.timeout = timeout; this.loadAny = parameters == null; this.OnCompleting = onCompleting; Transaction currentTransaction = Transaction.Current; if (currentTransaction == null && this.instanceManager.Host.IsLoadTransactionRequired) { this.committableTransaction = new CommittableTransaction(this.timeout); currentTransaction = committableTransaction; } if (currentTransaction != null) { this.transaction = currentTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete); } }
public static sysTx.TransactionScope Make(sysTx.DependentTransaction depTx) { return(Make(sysTx.TransactionScopeOption.Required, sysTx.IsolationLevel.ReadCommitted, 30d, depTx)); }
public TransScope(DependentTransaction dt) { dependentTransaction = dt; transactionScope = new TransactionScope(dt); }
// Create a dependent clone of the transaction that forwards requests to this object. // public DependentTransaction DependentClone( DependentCloneOption cloneOption ) { TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this); } if (cloneOption != DependentCloneOption.BlockCommitUntilComplete && cloneOption != DependentCloneOption.RollbackIfNotComplete) { throw new ArgumentOutOfRangeException(nameof(cloneOption)); } if (Disposed) { throw new ObjectDisposedException(nameof(Transaction)); } if (_complete) { throw TransactionException.CreateTransactionCompletedException(DistributedTxId); } DependentTransaction clone = new DependentTransaction( _isoLevel, _internalTransaction, cloneOption == DependentCloneOption.BlockCommitUntilComplete); if (etwLog.IsEnabled()) { etwLog.TransactionCloneCreate(clone, "DependentTransaction"); etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this); } return clone; }
public DependentTransaction DependentClone ( DependentCloneOption option) { DependentTransaction d = new DependentTransaction (this, option); dependents.Add (d); return d; }
public void TestTransactedAsyncConsumption() { PurgeDatabase(); PurgeAndFillQueue(MSG_COUNT * BATCH_COUNT); INetTxConnectionFactory factory = new NetTxConnectionFactory(ReplaceEnvVar(connectionURI)); using (INetTxConnection connection = factory.CreateNetTxConnection()) using (NetTxSession session = connection.CreateNetTxSession() as NetTxSession) { IQueue queue = session.GetQueue(testQueueName); IMessageConsumer consumer = session.CreateConsumer(queue); consumer.Listener += AsyncTxAwareOnMessage; // Be carefull, message are dispatched once this is done, so you could receive // a Message outside a TX. We use the awaitBatchProcessingStart event here to // gate te OnMessage callback, once that method returns the Message is ack'd and // no longer has a chance to participate in a TX. connection.Start(); for (int i = 0; i < BATCH_COUNT; ++i) { using (TransactionScope scoped = new TransactionScope(TransactionScopeOption.RequiresNew)) { session.Enlist(Transaction.Current); batchTxControl = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete); awaitBatchProcessingStart.Set(); scoped.Complete(); } // Reenlisting to fast seems to annoy the DTC. Also since DTC operations are // async we need to allow a little time for lag so that the last TX actually // completes before we start a new one. Thread.Sleep(250); } } // verify sql server has commited the transaction VerifyDatabaseTableIsFull(MSG_COUNT * BATCH_COUNT); // check messages are NOT present in the queue VerifyNoMessagesInQueue(); }