【发布时间】:2010-09-22 18:39:19
【问题描述】:
我在 Windows 服务中有一个工作流,它是一个定期执行工作的循环。这项工作在TryCatch 活动中完成。 Try 属性是一个 TransactionScope 活动,它包装了一些读取和更新数据库的自定义活动。当事务失败时,我希望任何导致此事件被TryCatch 捕获的异常。但是,我的工作流程中止。我的工作流程如下:
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) }
}
},
}
在我的情况下,数据库有时可能不可用,因此显然事务不会提交。在这种情况下会发生工作流中止并出现以下异常:
System.OperationCanceledException:处理当前工作项的错误导致工作流中止。
内部异常是:
System.Transactions.TransactionException:操作对于事务的状态无效。
这是有道理的,因为我刚刚关闭了数据库。但是,为什么我的 TryCatch 活动没有处理此异常?
编辑 1:一些附加信息。我使用WorkflowApplication 类运行工作流。为了更好地了解发生了什么,我指定了属性Aborted 和OnUnhandledException。当异常发生时,直接转到Aborted 并跳过OnUnhandledException(尽管这显然是一个未处理的异常)。
EDIT 2:我启用了调试日志,这提供了一些额外的见解。 “自定义数据库活动”成功运行完成。指示出现问题的第一个事件日志条目是详细级别消息:运行时事务已完成,状态为“已中止”。接下来我看到一条信息消息:WorkflowInstance Id: 'dbd1ba5c-2d8a-428c-970d-21215d7e06d9' E2E Activity(不确定这是什么意思)。之后的信息消息是:Activity 'System.Activities.Statements.TransactionScope', DisplayName: 'Transaction for run immediate checks', InstanceId: '389' has completed in the 'Faulted' state。
在此消息之后,我看到每个父级(包括 TryCatch 活动)都在“故障”状态下完成,并以我的工作流中止而结束。
编辑 3:需要明确的是,当任何“自定义数据库活动”中发生异常时,一切都会按预期进行。异常被捕获并且工作流继续。只有在TransactionScope 末尾事务无法提交时才会出错。请参阅从 Aborted 回调记录的以下堆栈跟踪:
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 类。
【问题讨论】:
-
只是一个猜测,但也许您需要捕获
TransactionException,而不是Exception。 -
我会尝试添加更多具有更具体异常类型的捕获,但我希望捕获通用
Exception将处理所有异常.. -
添加更具体的 catch 语句不起作用。我得到相同的结果:工作流中止。
-
您在使用 SqlWorkflowInstanceStore 吗?它使用的是同一个数据库吗?
-
我没有为此工作流配置
InstanceStore,因此它不会被持久化。我通过启用调试日志找到了一些额外的信息。我会把这个添加到问题中。
标签: c# transactions .net-4.0 workflow-foundation workflow-foundation-4