SqlPersistenceService持久化数据库

1.1  数据库安装

系统盘\Windows\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN

SqlPersistenceService_Schema.sql

SqlPersistenceService_Logic.sql

 1.2  数据库时间格式说明

SqlPersistenceService数据库中,时间值是GMT格式的,

这样做的目地是使用统一的时间轴,

如此可以解决一台在美国的服务器与一台在中国的服务器就可以协同工作时的时差问题

GMT比北京时间晚8小时

 1.3  表结构

1.3.1 InstanceState

对这个表我以前有一个错误的习惯性叫法,叫它实例表,其实应叫未完成事例的运行状态表

 

uidInstanceID  

state  

status 

unlocked   

blocked

info   

modified   

ownerID

ownedUntil 

nextTimer

 1.3.2 CompletedScope

uidInstanceID  

completedScopeID   

state  

modified   

 1.4  存储过程

 2     SqlWorkflowPersistenceService

SqlWorkflowPersistenceService作为一个PersistenceService的功能实现类加载到WorkflowRuntime中为引擎提供了一种使用SQLServer数据实现持久化的功能。

SqlWorkflowPersistenceService类是使用SQL数据库对工作流状态进行持久化的服务

为了能够使用SqlWorkflowPersistenceService,数据库还需要启动DTC服务

 2.1  加载说明

每当引擎起动时(StartRuntime),只要InstanceState表中有实例数据,就会将该实例载入引擎中,并将ownedUntil字段设为加载的时间

 

1.  引擎使用GetWorkflow方法,可通过SqlWorkflowPersistenceService服务将存于数据库中的实例加载并返回

2.  实例使用load方法,可触发引擎的WorkflowLoaded事件

3.  没有经过持久化的实例,调用load方法不会出错,也不产生引擎的WorkflowLoaded事件

4.  加载的持久化实例不用load方法也能直接操作,但这样不会产生引擎的WorkflowLoaded事件,调用load方法可以产生引擎的WorkflowLoaded事件,除此之外,我没跟出什么其他的

5.  引擎.GetWorkflow(GUID)方法可以返回一个引擎中存在的实例

如果引擎中不存在,SqlWorkflowPersistenceService服务会到数据库中找该实例,并将其加载到引擎

 

如果引擎中没有指定GUID的实例,会报Workflow with id "GUID" not found in state persistence store.

 

如没加载SqlWorkflowPersistenceService服务报的异常为The workflow hosting environment does not have a persistence service as required by an operation on the workflow instance

 

 2.2  持久化说明

1.  当引擎停止时(StopRuntime),就会将引擎内的所有工作流实例存入InstanceState表,ownedUntil字段为空

注:没加载SqlWorkflowPersistenceService服务时,

引擎停止后,引擎并没有释放,引擎中的实例也存在,只是所有的执行都被系统级挂起,

当重新启动引擎时,所有的实例还可继续运行

 2.  实例使用Unload方法,通过加载到引擎中的SqlWorkflowPersistenceService服务,完成实例的内存移出与保存到数据库的操作

3.  没有加载SqlWorkflowPersistenceService时,实例的TryUnload方法会报异常。

4.  如果调用UnLoad方法时,实例在挂起状态时(:实例.Suspend)

 

status值为2

info值为Suspend方法的参数

 

unlocked值为1

blocked值为0

modified为操作的时间

nextTimer9999-12-31 23:59:59.997

5.  如果调用UnLoad方法时,实例在引擎中创建后,还没开始执行前,

status值为4

info值为空

其他同上

2.3  idle状态的持久化

idle状态即空闲状态,如Delay结点就能使实例进入idle状态,并触发引擎的WorkflowIdled事件。SqlWorkflowPersistenceService会不停的刷InstanceState,发现有状态为Delay的实例,且nextTimer小于当前时间,就执行他。所以,持久化Delay状态的实例,不用人为加载运行,SqlWorkflowPersistenceService服务会自动运行的。

1.  如果调用UnLoad方法时,实例在运行到Delay结点的idle状态

如调用Unload方法

status值为0

unlocked值为1

blocked值为1

nextTimer值为实际Delay应苏醒的时间。

 

2.  使用SqlWorkflowPersistenceService可以实现每当实例进入idle状态后,自动将调用Unload将其持久化

可以使用SqlWorkflowPersistenceService类的构造函数的unloadOnIdle参数设置是否自动持久化 

3.  DelayActivity的延时修正

DelayActivity是一个提供延时处理的组件,当实例处于Idle状态时,实例的UnloadOnIdle被置位。等时间到达后,该实例继续向下执行,

这里有一个问题,就是工作流实例被不同的进程进行处理时的延时修正问题

SqlWorkflowPersistenceService 提供了这个功能

InstanceState表的NextTime字段就是用于修正延时时间用的。

SqlWorkflowPersistenceService的构造函数中还有一个参数LoadingInterval

此参数可以使引擎在多少时间间隔内去检测那些超时的工作流实例,如果超时了则自动进行加载并运行。

也就是引擎要过多久才去刷一次数据库,以查检是否有到时的实例

 

4.  重新加载工作流后,计时器不会恢复操作的错误

WF的一个BUG

http://support.microsoft.com/kb/932394/zh-cn

 

 2.4  锁定问题

 

工作流引擎加载工作流实例时,锁定该实例,这样其它引擎就不能加载这个工作流实例了。

当工作流实例保存回数据库后便解除锁定状态,这样其它引擎便可加载该工作流实例了。

当加载工作流实例的进程突然死掉,则数据库的锁定状态是不是永远都不能解锁了。

SqlWorkflowPersistenceService的构造函数中有一个参数instanceOwnershipDuration,指明了锁定工作流实例的时间限制。

可以依据现实情况去估计一个工作流实例在某一个环节处理所用的时间进行设置,如10分钟。如果处理时间超过这个值则会被其它引擎自动解锁,也就是说解锁可以由其它引擎来进行而不依赖于当前的进程

实现过程:

InstanceState表里记录着工作流的实例,OwnedUntil字段记录了该工作流实例锁定的到期时间,当引擎加载一个工作流实例时,它会将当前时间加上SqlWorkflowPersistenceService构造函数中的instanceOwnershipDuration参数指定的时间,并把相加的时间存放到OwnedUntil字段里。

数据库里有一个存储过程UnlockInstanceState,其它的工作流引擎就是用此存储过程来解锁被锁定的工作流实例。这个过程是引擎自动完成的.

 

 2.5  构造函数说明

2.5.1 第一种

new SqlWorkflowPersistenceService(string connectionString)

 

 

参数:string connectionString   是持久化的数据库连接字串

2.5.2 第二种

new SqlWorkflowPersistenceService(string connectionString,

bool unloadOnIdle,

TimeSpan instanceOwnershipDuration ,

TimeSpan loadingInterval)

参数:string connectionString   是持久化的数据库

参数:bool unloadOnIdle       为真表示自动将调用UnloadDelay状态的实例持久化

参数:TimeSpan instanceOwnershipDuration  引擎锁定实例,防止其他引擎加载的时间

参数:TimeSpan loadingInterval  是引擎自动到数据库中查找是否有idle到实例的时间步长

 2.6  属性

EnableRetries属性

 

LoadingInterval属性

Gets the length of the loading interval.

ServiceInstanceId属性

Gets the service instance identifier.

 2.7  GetAllWorkflows()方法

Retrieves instance descriptions of all persisted workflows.

得到所有被持久化的实例说明,

1. 当实例被持久化后,实例信息从引擎列表中移出,会添加到持久化列表中

2. 当引擎启动后,会从持久化数据库中加载所有被持久化的数据,这时引擎列表与该列表内容相同

3. 当实例完成后,实例信息从引擎列表中移出,也从持久化列表中移出

 

SqlWorkflowPersistenceService SWPS=new SqlWorkflowPersistenceService("constring");

System.Collections.IEnumerable workflows = SWPS.GetAllWorkflows();

foreach (SqlPersistenceWorkflowInstanceDescription instanceDescription in workflows)

{

string v=instanceDescription.SuspendOrTerminateDescription;

Guid guid =instanceDescription.WorkflowInstanceId;

bool b = instanceDescription.IsBlocked;

DateTime time = instanceDescription.NextTimerExpiration.Value;

WorkflowStatus st = instanceDescription.Status;

                //WorkflowStatus.Completed

                //WorkflowStatus.Created

                //WorkflowStatus.Running

                //WorkflowStatus.Suspended

                //WorkflowStatus.Terminated

}

 2.8  LoadExpiredTimerWorkflowIds()方法

Retrieves a list of completed timer instances.As IList(Of Guid)

SqlWorkflowPersistenceService SWPS=new SqlWorkflowPersistenceService("constring");

 

foreach (Guid guid in SWPS.LoadExpiredTimerWorkflowIds())

{

string v = guid.ToString();

}

 

3     实例与持久化相关的方法

Load

加载实例

加载的持久化实例不用load方法也能直接操作,

但这样不会产生引擎的WorkflowLoaded事件,

调用load方法可以产生引擎的WorkflowLoaded事件,

除此之外,我没跟出什么其他的

TryUnload

从内存中卸载实例,返回Boolean

 

如果实例处于idlesuspended状态,

 

TryUnload persistence服务将实例从内容中移除,并将该实例持久化到数据库中,

 

如果没有persistence服务加载到引擎,TryUnload 方法会产生一个 InvalidOperationException. 异常。

 

如果实例被成功的持久化, 引擎将触发 WorkflowUnloaded事件并返回true.

 

如果实例已经unloaded,terminated,aborted,completed,则返回false

 

将实例从内存中移出可以释放系统资源

Unload

 

Unload 是同步的.其他同上

 

 4     引擎引持久化相关的事件

 

WorkflowUnloaded

 

WorkflowLoaded

 

 

 

 

 

 

 

 

自:http://www.cnblogs.com/foundation/category/212578.html

你可能感兴趣的:(service)