Наследование: System.Transactions.Transaction, System.Runtime.Serialization.ISerializable
Пример #1
0
            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;
            }
        }
Пример #4
0
        // 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);
        }
Пример #5
0
        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);
            }
        }
Пример #7
0
        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;
 }
Пример #10
0
		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);
 }
Пример #12
0
 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)
     }));
 }
Пример #13
0
		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();
                }

            }
        }
Пример #17
0
        // 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);
        }
Пример #18
0
        // 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;
            }
        }
Пример #19
0
 /// <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);
 }
 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);
 }
Пример #21
0
        /// <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;
        }
        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;
            }
        }
Пример #23
0
        // 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;
        }
Пример #24
0
        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);
     }
 }
Пример #26
0
        public void Dispose()
        {
            if (refDisposeCount > 0)
                refDisposeCount -= 1;
            else
            {
                transactionScope.Dispose();
                transactionScope = null;

                if (dependentTransaction != null)
                {
                    dependentTransaction.Dispose();
                    dependentTransaction = null;
                }
            }
        }
Пример #27
0
		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);
                }
            }
Пример #33
0
 public static sysTx.TransactionScope Make(sysTx.DependentTransaction depTx)
 {
     return(Make(sysTx.TransactionScopeOption.Required,
                 sysTx.IsolationLevel.ReadCommitted, 30d, depTx));
 }
Пример #34
0
 public TransScope(DependentTransaction dt)
 {
     dependentTransaction = dt;
     transactionScope = new TransactionScope(dt);
 }
Пример #35
0
        // 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;
        }
Пример #36
0
		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();
        }