状态机 WF:工作流终止问题

发布于 2024-08-27 09:47:07 字数 264 浏览 11 评论 0原文

我们有一个状态机工作流程来维护用户提交的应用程序的状态。我遇到的问题之一与工作流程终止有关。在其中一个州,我遇到了一个错误。当应用程序达到该状态时,它会抛出异常,因此调用工作流的终止事件,并且特定的工作流实例从持久性数据库中删除。所以我无法再加载该工作流实例。我希望,如果其中一个状态出现错误,就会抛出异常(这样我们就知道问题是什么),但整个工作流实例不应该消失。故障处理程序活动能否确保工作流不会终止。另外,有没有一种方法,当调用终止事件时,实例不会从持久性存储中删除。

感谢您的任何帮助/建议。

We have a state machine workflow for maintaining the state of an application submitted by a user. One of the issues I am having is related to workflow termination. In one of the states, I had a bug. When the application reached that state, it threw an exception and as a result, the terminate event of the workflow was called and the particular workflow instance got removed from the persistence database. So I am not able to load that workflow instance anymore. I would have hoped, if there is an error in one of the states, an exception would be thrown(so that we know what the issue is), yet the entire workflow instance should not disappear. Can the fault handler activity ensure that the workflow does not terminate. Also, is there a way, when the terminate event is called, the instances do not get removed from the persistence store.

Thanks for any help/suggestions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我不咬妳我踢妳 2024-09-03 09:47:08

当工作流中抛出异常时,异常将有效地通过活动祖先“冒泡”,直到出现以下情况:

  1. 由故障处理程序活动
  2. 处理 到达根活动(即:工作流本身),此时工作流将获得终止。

在正确的位置为所有可能的异常创建故障处理程序是一种很好的做法。使用故障处理程序活动,您可以恢复工作流实例,并有效地将状态机设置回可用状态,而不是终止它。

一旦工作流终止,它就无法使用,因此一旦发生终止,将其保留在持久性存储中就没有任何好处,这就是它被删除的原因。所以你可以看到,关键是阻止它意外终止。

最后一点提示。当工作流终止时,导致终止的异常将作为 WorkflowTermulatedEventArgs 对象的 Exception 属性发送到事件侦听器。我绝对建议使用某种日志记录机制来捕获它并将其输出到某个地方,这样如果您将来遇到由于某种原因而未被捕获的错误,那么追踪它们会更容易。

When an Exception is thrown in a workflow, the Exception will effectively "bubble up" through activity ancestors until it is either:

  1. Handled by a Fault Handler activity
  2. Reaches the root activity (ie: The workflow itself), at which point the workflow will get terminated.

It is good practice to create fault handlers for all possible Exceptions in the right places. Using a fault handler activity you can recover the workflow instance, and effectively set the state machine back into a usable state rather than have it terminate.

Once a workflow has terminated it is unusable, so there would be no benefit to retaining it in the persistence store once the termination occurs, which is why it gets removed. So you can see, the key is to stop it terminating unexpectedly.

One final tip. When a workflow does terminate, the exception that caused the termination is sent to event listeners as the Exception property of the WorkflowTerminatedEventArgs object. I would absolutely recommend having some sort of logging mechanism to catch that and output it somewhere so that if you experience bugs in future that are for some reason uncaught, it will be much easier to track them down.

携君以终年 2024-09-03 09:47:08

我创建了一个自定义 SQL 工作流持久性服务,可防止工作流实际终止 - 从而使工作流处于导致错误发生的转换之前的先前状态:

public class CustomSqlWorkflowPersistenceService : SqlWorkflowPersistenceService
    {
        public CustomSqlWorkflowPersistenceService (string connectionString) : base(connectionString)
        {
        }

        public CustomSqlWorkflowPersistenceService (NameValueCollection parameters) : base(parameters)
        {
        }

        public CustomSqlWorkflowPersistenceService (string connectionString, bool unloadOnIdle, TimeSpan instanceOwnershipDuration, TimeSpan loadingInterval) : base(connectionString, unloadOnIdle, instanceOwnershipDuration, loadingInterval)
        {
        }

        protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
        {
            WorkflowStatus workflowStatus = GetWorkflowStatus(rootActivity);
            if (workflowStatus == WorkflowStatus.Terminated)
            {
                string workflowError = GetSuspendOrTerminateInfo(rootActivity);
                if (!string.IsNullOrEmpty(workflowError))
                {
                    string error = string.Format("Workflow terminated, forcing an abort! {0}", workflowError);
                    throw new Exception(error);
                }
            }
            base.SaveWorkflowInstanceState(rootActivity, unlock);
        }
    }

如果您想强制 WF 执行此操作,这显然会很痛苦终止,但我相信你可以解决这个问题。

I created a custom SQL Workflow Persistence Service that prevents the workflow from actually terminating - thus leaving the workflow in the previous state before the transition that caused the error took place:

public class CustomSqlWorkflowPersistenceService : SqlWorkflowPersistenceService
    {
        public CustomSqlWorkflowPersistenceService (string connectionString) : base(connectionString)
        {
        }

        public CustomSqlWorkflowPersistenceService (NameValueCollection parameters) : base(parameters)
        {
        }

        public CustomSqlWorkflowPersistenceService (string connectionString, bool unloadOnIdle, TimeSpan instanceOwnershipDuration, TimeSpan loadingInterval) : base(connectionString, unloadOnIdle, instanceOwnershipDuration, loadingInterval)
        {
        }

        protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
        {
            WorkflowStatus workflowStatus = GetWorkflowStatus(rootActivity);
            if (workflowStatus == WorkflowStatus.Terminated)
            {
                string workflowError = GetSuspendOrTerminateInfo(rootActivity);
                if (!string.IsNullOrEmpty(workflowError))
                {
                    string error = string.Format("Workflow terminated, forcing an abort! {0}", workflowError);
                    throw new Exception(error);
                }
            }
            base.SaveWorkflowInstanceState(rootActivity, unlock);
        }
    }

This is obviously going to be a pain if you want to force a WF to terminate, but I'm sure you can work around that.

七堇年 2024-09-03 09:47:08

我正在使用 SqlWorkflowPersistence,作为对此的修复,我执行了以下操作:

在“WorkflowPersistence”数据库中,我们有 SP“InsertInstanceState”,它会删除实例。我评论了删除实例的代码。

看起来可行,但我不确定这是否是正确的方法。

下面显示了我更改的部分 SP。

IF
@status=1 OR @status=3          
    BEGIN      

/* DELETE FROM [dbo].[InstanceState] WHERE uidInstanceID=@uidInstanceID AND ((ownerID = @ownerID AND ownedUntil>=@now) 
 OR (ownerID IS NULL AND @ownerID IS NULL ))          
*/
    END  

I am using SqlWorkflowPersistence, as a fix for this I did the below:

In 'WorkflowPersistence' DB, we have SP 'InsertInstanceState' which deletes the instance. I commented the code which deletes the instance.

Looks like its working BUT I am not sure if this is correct way.

Part of the SP is shown below which I changed.

IF
@status=1 OR @status=3          
    BEGIN      

/* DELETE FROM [dbo].[InstanceState] WHERE uidInstanceID=@uidInstanceID AND ((ownerID = @ownerID AND ownedUntil>=@now) 
 OR (ownerID IS NULL AND @ownerID IS NULL ))          
*/
    END  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文