本文介绍了从工作流异常逃脱尽管TryCatch活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有内部的Windows服务的工作流程,是执行定期工作循环。这项工作是在一个 TryCatch完成 活动。该 尝试 属性是 的TransactionScope 的活动,包装一些读取和更新数据库自定义活动。如果交易失败,我会想到这引起任何异常被捕获的 TryCatch 。然而,我的工作流程中止。工作流程我已经是这样的:

I have a workflow inside a Windows Service that is a loop that performs work periodically. The work is done inside a TryCatch activity. The Try property is a TransactionScope activity that wraps some custom activities that read and update a database. When the transaction fails, I would expect any exception that caused this to be caught by the TryCatch. However, my workflow aborts. The workflow I have is the following:

var wf = new While(true)
{
    Body = new Sequence
    {
        Activities =
        {
            new TryCatch
            {
                Try = new TransactionScope
                {
                    IsolationLevel = IsolationLevel.ReadCommitted,
                    Body = new Sequence
                    {
                        Activities = { ..custom database activities.. }
                    },
                    AbortInstanceOnTransactionFailure = false
                },
                Catches =
                {
                    new Catch<Exception>
                    {
                        Action = new ActivityAction<Exception>
                        {
                            Argument = exception,
                            Handler = ..log error..
                        }
                    }
                }
            },
            new Delay { Duration = new InArgument<TimeSpan>(duration) }
        }
    },
}

在我的情况下,它可能是数据库不可用,有时候如此明显的事务将不会提交。会发生什么事在这种情况下,工作流中止与以下异常:

In my case, it's possible that the database is sometimes unavailable so obviously the transaction won't commit. What happens in this case is that the workflow aborts with the following exception:

System.OperationCanceledException:错误处理当前工作项已经引起了工作流程中止

内的例外是:

System.Transactions.TransactionException:操作是无效的事务的状态

这是有道理的,因为我刚才关闭数据库。但是,为什么没有这个异常由我的 TryCatch 活动处理的?

This makes sense because I have just switched off the database. However, why isn't this exception handled by my TryCatch activity?

修改1 :一些额外的信息。我运行使用 WorkflowApplication 类。为了更好地看看这是怎么回事,我指定的属性 中止 OnUnhandledException 。当异常发生时,它会直接中止 OnUnhandledException 跳过(尽管这显然是一个未处理的异常)。

EDIT 1: Some additional information. I run the workflow using the WorkflowApplication class. To better see what's going on, I specified the properties Aborted and OnUnhandledException. When the exception occurs, it goes directly to Aborted and OnUnhandledException is skipped (although this is clearly an unhandled exception).

编辑2 :我启用了调试日志,这提供了一些新的见解。在自定义数据库活动成功完成运行。这表明,什么是错的第一个事件日志条目是一个详细级别的消息:运行时的交易已经完成了与国家中止的。接下来,我看到一个信息消息: WorkflowInstance编号:'dbd1ba5c-2d8a-428C-970d-21215d7e06d9端到端活动的(不知道这是什么意思)。而在此之后的信息消息是:活动System.Activities.Statements.TransactionScope,显示名称:交易运行立即检查,INSTANCEID:389已在断陷状态完成的。

EDIT 2: I enabled the debug log and this provides some additional insight. The 'custom database activities' successfully run to completion. The first event log entry that indicates that something is wrong is a Verbose level message: The runtime transaction has completed with the state 'Aborted'. Next I see an Information message: WorkflowInstance Id: 'dbd1ba5c-2d8a-428c-970d-21215d7e06d9' E2E Activity (not sure what this means). And the Information message after that is: Activity 'System.Activities.Statements.TransactionScope', DisplayName: 'Transaction for run immediately checks', InstanceId: '389' has completed in the 'Faulted' state.

这个消息后,我看到每个父母(包括 TryCatch 的活动)完成了断陷的状态,我的工作流程的人工流产结束。

After this message, I see that each parent (including the TryCatch activity) completes in the 'Faulted' state, ending with the abortion of my workflow.

修改3 :需要明确的是,一切都运行时异常中的任何一种'自定义数据库活动'出现预期。异常被捕获和工作流继续。它只是不顺心时,事务不能提交在的TransactionScope 的结束。请参阅以下堆栈跟踪的是从中止的回调记录:

EDIT 3: To be clear, everything works as expected when an exception occurs in any of the 'custom database activities'. The exception is caught and the workflow continues. It only goes wrong when the transaction can't commit at the end of the TransactionScope. See the following stacktrace that is logged from the Aborted callback:

at System.Transactions.TransactionStateInDoubt.Rollback(InternalTransaction tx, Exception e)
at System.Transactions.Transaction.Rollback(Exception e)
at System.Activities.Runtime.ActivityExecutor.CompleteTransactionWorkItem.HandleException(Exception exception)

如果您按照从 TransactionScope.OnCompletion调用(...),最终你会在 ActivityExecutor 从堆栈跟踪类。

If you follow the calls from TransactionScope.OnCompletion(...), eventually you will arrive at the ActivityExecutor class from the stacktrace.

推荐答案

交易提交异步和事后。不能作出反应,交易的故障,因为在所述资源管理水平的问题提交。

Transactions commit asynchronously and after the fact. You can't react to a failure of the transaction to commit because of a problem at the resource manager level.

正如你指出的那样,你可以发生在你的活动异常处理。如果你看一下跟踪记录您的工作流程我的猜测是,你会看到之前的交易中止TryCatch活动关闭。

As you pointed out, you can deal with exceptions that occur in your activities. If you look at the tracking records for your workflow my guess is that you would see the TryCatch activity is closed prior to the transaction abort.

很多年前,当我在COM +团队我研究过这个问题,因为人们往往希望在这种情况下,一个事务性组件(或工作流),以能够应对的事务项目经理中止。

Many years ago when I was a program manager in the COM+ team I studied this issue because often people want a transactional component (or workflow) as in this case to be able to react to a transaction abort.

该交易的决议的异步特性意味着你根本无法在组件本身的反应。解决的办法是在呼叫方然后可以采取某些行动作出反应。

The async nature of the resolution of the transaction means that you simply cannot react to it in the component itself. The solution is to react in the caller which can then take some action.

设计假设是,一旦交易已经终止,任何关于国家aqcuired在交易中可以安全使用 - 它都将被丢弃,因为该交易被中止

The design assumption is that once a transaction has aborted, nothing about state aqcuired in the transaction can be safely used - it will all be discarded because the transaction is aborted.

这篇关于从工作流异常逃脱尽管TryCatch活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 23:18