非持久工作流实例

创建一个新的工作流实例以在 SqlWorkflowInstanceStore 中持久化其状态时,服务主机会在实例存储区中为该服务创建一个条目。 随后,当工作流实例首次持久化时,SqlWorkflowInstanceStore 会存储当前实例状态。 如果工作流托管在 Windows 进程激活服务中,则首次保存实例时,服务部署数据也会写入实例存储。

只要工作流实例尚未持久化,它就处于 非持久 状态。 处于此状态时,应用程序域回收、主机故障或计算机故障后,无法恢复工作流实例。

非持久状化态

尚未持久化的持久工作流实例在下列情况下将保持非持久化状态:

  • 服务主机在第一次持久保存工作流实例之前崩溃。 工作流实例保留在实例存储中,不会恢复。 如果相关消息到达,工作流实例将再次处于活动状态。

  • 工作流实例在首次持久化之前遇到异常。 根据UnhandledExceptionAction返回的情况,会发生以下几种情况:

    • UnhandledExceptionAction 设置为 Abort:发生异常时,服务部署信息将写入实例存储,并从内存中卸载工作流实例。 工作流实例保持非持久化状态,无法重新加载。

    • UnhandledExceptionAction 设置为 CancelTerminate:发生异常时,服务部署信息将写入实例存储,并将活动实例状态设置为 Closed

若要最大程度地降低遇到已卸载非持久化工作流实例的风险,建议您在工作流生命周期的早期持久化工作流。

非持久化实例的检测和移除

SqlWorkflowInstanceStore不会从实例存储中移除任何非持久化的工作流实例。 它也不会移除任何具有关联的非持久化工作流实例的已过期锁定所有者。

建议管理员定期检查实例存储中是否有非持久化实例。 只要管理员知道此工作流不会收到相关消息,管理员就可以从实例存储中删除这些实例。 例如,如果实例已在数据库中几个月,并且已知工作流的生存期通常为数天,则可以放心地假设这是已崩溃的初始化实例。

若要在 SQL 工作流实例存储中查找非持久化实例,可以使用以下 SQL 查询:

  • 此查询查找所有未持久保存的实例,并返回 ID 和创建时间(以 UTC 时间存储)。

    select InstanceId, CreationTime
        from [System.Activities.DurableInstancing].[Instances]
        where IsInitialized = 0
    
  • 此查询查找尚未持久保存且未加载的所有实例,并返回 ID 和创建时间(以 UTC 时间存储)。

    select InstanceId, CreationTime
        from [System.Activities.DurableInstancing].[Instances]
        where IsInitialized = 0
            and CurrentMachine is NULL
    
  • 此查询查找所有未持久保存的挂起实例,并返回 ID、创建时间(以 UTC 时间存储)、挂起原因和异常名称。

    select InstanceId, CreationTime, SuspensionReason, SuspensionExceptionName
        from [System.Activities.DurableInstancing].[Instances]
        where IsInitialized = 0
            and IsSuspended = 1
    

删除非持久化实例时务必小心。 通常,移除由 WorkflowServiceHost 创建的已挂起或未加载的非持久化实例是安全的。 可以通过使用以下 SQL 命令从视图中删除这些特定实例,替换正确的实例 ID,从而从 [System.Activities.DurableInstancing].[Instances] 存储中删除这些实例。

delete [System.Activities.DurableInstancing].[Instances]
    where InstanceId=’078a9bc4-ada5-4f9e-8cce-b0eb0009995f’

警告

我们不建议删除所有非持久化实例,因为这包括刚刚创建且尚未持久保存的实例。