如何:查询非持有化实例

创建某个服务的新实例时,如果该服务已定义 SQL 工作流实例存储行为,则服务主机将在实例存储区中为该服务实例创建一个初始项。 随后,当该服务实例第一次持久化时,SQL 工作流实例存储行为会将当前实例状态与执行激活、恢复和控制操作所需的其他数据一起存储。

如果在创建某个实例的初始项后没有持久化该实例,则认为该服务实例处于非持久化状态。 可以查询和控制所有持久化服务实例。 不能查询和控制非持久化服务实例。 如果由于未处理的异常而挂起非持久化实例,则可以对该实例进行查询,但不能对它控制。

尚未持久化的持久服务实例在下列情况中将保持非持久化状态:

  • 在第一次持久化实例之前,服务主机出现故障。 实例的初始项保留在实例存储区中。 该实例不可恢复。 如果获得关联的消息,则该实例再一次进入活动状态。

  • 该实例第一次持久化之前遇到未经处理的异常。 出现下列情况

    • 如果 UnhandledExceptionAction 属性的值设置为 Abandon,则将服务部署信息写入实例存储区,并从内存中卸载该实例。 在持久性数据库中,该实例保持非持久化状态。

    • 如果 UnhandledExceptionAction 属性的值设置为 AbandonAndSuspsend,则将服务部署信息写入持久性数据库,并将实例状态设置为 Suspended。 无法恢复、取消或终止该实例。 由于该实例尚未持久化,服务主机无法加载该实例,因此该实例的数据库项不完整。

    • 如果 UnhandledExceptionAction 属性的值设置为 Cancel 或 Terminate,则将服务部署信息写入实例存储区,并将实例状态设置为 Completed。

下面的部分提供一些示例查询,用于在 SQL 持久性数据库中查找未持久化实例并从数据库删除这些实例。

查找所有尚未持久化的实例

下面的 SQL 查询返回所有尚未保存到持久性数据库的实例的 ID 和创建时间。

select InstanceId, CreationTime from [System.Activities.DurableInstancing].[Instances] where IsInitialized = 0;

查找所有尚未持久化并且未加载的实例

下面的 SQL 查询返回所有未持久化且未加载的实例的 ID 和创建时间。

select InstanceId, CreationTime from [System.Activities.DurableInstancing].[Instances] where IsInitialized = 0 and CurrentMachine is NULL;

查找所有尚未持久化的挂起的实例

下面的 SQL 查询返回所有未持久化且处于挂起状态的实例的 ID、创建时间、挂起原因和挂起异常名称。

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

从持久性数据库中删除非持久化实例

应定期检查实例存储区中的非持久化实例,如果确认该实例将不会接收到关联的消息,则从实例存储区中移除该实例。 如果某个实例在数据库中已经存在了数月,并且您知道工作流通常只有几天的生存期,则可以放心地认为这是一个已经崩溃的未初始化的实例。

通常,删除未挂起或未加载的非持久化实例是安全的。 不应删除所有非持久化实例,因为此实例集还包括那些刚刚创建但尚未持久化的实例。 只应删除那些因加载实例的工作流服务主机引发了异常或实例本身引发了异常而留下的非持久化实例。

警告

从实例存储区删除非持久化实例可减少存储的大小,并可能提高存储操作的性能。