protected internal override void CommitWorkBatch(WorkflowCommitWorkBatchService.CommitWorkBatchCallback commitWorkBatchCallback)
        {
            DbRetry retry      = new DbRetry(this._enableRetries);
            short   retryCount = 0;

Label_000E:
            if (null != Transaction.Current)
            {
                retryCount = retry.MaxRetries;
            }
            try
            {
                base.CommitWorkBatch(commitWorkBatchCallback);
            }
            catch (Exception exception)
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "DefaultWorkflowCommitWorkBatchService caught exception from commitWorkBatchCallback: " + exception.ToString());
                if (!retry.TryDoRetry(ref retryCount))
                {
                    throw;
                }
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "DefaultWorkflowCommitWorkBatchService retrying commitWorkBatchCallback (retry attempt " + retryCount.ToString(CultureInfo.InvariantCulture) + ")");
                goto Label_000E;
            }
        }
        protected internal override void CommitWorkBatch(WorkflowCommitWorkBatchService.CommitWorkBatchCallback commitWorkBatchCallback)
        {
            //
            // Disable retries by default, reset to allow retries below if we own the tx
            DbRetry dbRetry      = new DbRetry(_enableRetries);
            short   retryCounter = dbRetry.MaxRetries;

            while (true)
            {
                //
                // When using LocalTransaction handle block access to the connection
                // in the transaction event handlers until all IPendingWork members have completed
                ManualResetEvent     handle         = new ManualResetEvent(false);
                Transaction          tx             = null;
                SharedConnectionInfo connectionInfo = null;

                try
                {
                    if (null == Transaction.Current)
                    {
                        //
                        // It's OK to retry here as we own the tx
                        retryCounter = 0;
                        //
                        // Create a local, non promotable transaction that we share with our OOB services
                        tx             = new CommittableTransaction();
                        connectionInfo = new SharedConnectionInfo(this.dbResourceAllocator, tx, false, handle);
                    }
                    else
                    {
                        //
                        // Can't retry as we don't own the tx
                        // Create a dependent transaction and don't restrict promotion.
                        tx             = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
                        connectionInfo = new SharedConnectionInfo(this.dbResourceAllocator, tx, true, handle);
                    }

                    AddToConnectionInfoTable(tx, connectionInfo);

                    using (TransactionScope ts = new TransactionScope(tx))
                    {
                        try
                        {
                            commitWorkBatchCallback();
                            ts.Complete();
                        }
                        finally
                        {
                            RemoveConnectionFromInfoTable(tx);
                            //
                            // Unblock transaction event handlers
                            handle.Set();
                        }
                    }

                    CommittableTransaction committableTransaction = tx as CommittableTransaction;
                    if (committableTransaction != null)
                    {
                        committableTransaction.Commit();
                    }

                    DependentTransaction dependentTransaction = tx as DependentTransaction;
                    if (dependentTransaction != null)
                    {
                        dependentTransaction.Complete();
                    }

                    break;
                }
                catch (Exception e)
                {
                    tx.Rollback();

                    WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "SharedConnectionWorkflowCommitWorkBatchService caught exception from commitWorkBatchCallback: " + e.ToString());

                    if (dbRetry.TryDoRetry(ref retryCounter))
                    {
                        WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SharedConnectionWorkflowCommitWorkBatchService retrying commitWorkBatchCallback (retry attempt " + retryCounter.ToString(System.Globalization.CultureInfo.InvariantCulture) + ")");
                        continue;
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    handle.Close();
                    if (tx != null)
                    {
                        tx.Dispose();
                    }
                }
            }
        }
Пример #3
0
        protected internal override void CommitWorkBatch(WorkflowCommitWorkBatchService.CommitWorkBatchCallback commitWorkBatchCallback)
        {
            ManualResetEvent event2;
            DbRetry          retry      = new DbRetry(this._enableRetries);
            short            maxRetries = retry.MaxRetries;

Label_0013:
            event2 = new ManualResetEvent(false);
            Transaction          transaction    = null;
            SharedConnectionInfo connectionInfo = null;

            try
            {
                if (null == Transaction.Current)
                {
                    maxRetries     = 0;
                    transaction    = new CommittableTransaction();
                    connectionInfo = new SharedConnectionInfo(this.dbResourceAllocator, transaction, false, event2);
                }
                else
                {
                    transaction    = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
                    connectionInfo = new SharedConnectionInfo(this.dbResourceAllocator, transaction, true, event2);
                }
                this.AddToConnectionInfoTable(transaction, connectionInfo);
                using (TransactionScope scope = new TransactionScope(transaction))
                {
                    try
                    {
                        commitWorkBatchCallback();
                        scope.Complete();
                    }
                    finally
                    {
                        this.RemoveConnectionFromInfoTable(transaction);
                        event2.Set();
                    }
                }
                CommittableTransaction transaction2 = transaction as CommittableTransaction;
                if (transaction2 != null)
                {
                    transaction2.Commit();
                }
                DependentTransaction transaction3 = transaction as DependentTransaction;
                if (transaction3 != null)
                {
                    transaction3.Complete();
                }
            }
            catch (Exception exception)
            {
                transaction.Rollback();
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "SharedConnectionWorkflowCommitWorkBatchService caught exception from commitWorkBatchCallback: " + exception.ToString());
                if (!retry.TryDoRetry(ref maxRetries))
                {
                    throw;
                }
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SharedConnectionWorkflowCommitWorkBatchService retrying commitWorkBatchCallback (retry attempt " + maxRetries.ToString(CultureInfo.InvariantCulture) + ")");
                goto Label_0013;
            }
            finally
            {
                event2.Close();
                if (transaction != null)
                {
                    transaction.Dispose();
                }
            }
        }