天天看点

【转】工作流持久化的几点说明

WF工作流实例持久化(钝化)在工作流项目中相当的重要,在实际业务中几乎所有的业务流都需要较长时间才能执行完毕,这样就需要把未完成的业务流持久化到数据库或者文件中。

WF自身提供了SqlWorkflowPersistenceService服务以支持实例持久化。

public SqlWorkflowPersistenceService( string connectionString, bool unloadOnIdle, TimeSpan instanceOwnershipDuration, TimeSpan loadingInterval )

参数说明:

connectionString:数据库连接字符串

unloadOnIdle:是否启用自动钝化

instanceOwnershipDuration:锁定持续时间

loadingInterval:引擎轮询检测时间间隔

对数据库连接字副串就不需要多讲了,关键在后面三个参数。

unloadOnIdle在我们目前看到MS提供的例子中都是设为true的,这样好处是我们不用关心持久化问题,工作流引擎会自动实现( 空闲的时候进行持久化操作)。我一般都是设置为false,通过workflowruntime的Idled事件来完成持久化。

曾经在网上看到有朋友说如果设置为true会产生很操蛋的问题:实例一旦被持久化,我们从数据库retrieve这个实例后,就没有办法使用了,具体表现 是工作流不能接收调用方发起的事件,经过测试好像不存在这个问题,至少目前没有发现这个情况(也有可能vs2008 RTM版本附带的wf已经不存在这个问题)

instanceOwnerShipDuration:这个参数设置了工作流实例加载后被引擎锁定时间,强烈建议不要设置为0,一旦为0就等于不锁定了, 结果就是谁都可以retrieve这个实例,这就违背了workflow的原则(一家之言)。具体时间的长短根据业务类型的不同做适当调整。

loadingInterval:通过它完成系统的自动化操作,具体有那些作用俺也没有测试出来:(不过不建议设置时间太短,太短会对数据库造成压力,从事件探查器可以看到WorkflowRuntime在不挺的访问数据库。

SqlWorkflowPersistenceService服务主要依赖InstanceState、CompletedScope

InstanceState表记录了还没有执行完成的工作流实例,CompletedScope协助完成对工资流事务的支持。

InstanceState表字段说明:

uidInstanceID:实例Id,建议跟业务单据Id绑定在一起,如果您的系统是用int或者其他类型的主键就比较麻烦了。

state:工作流实例被持久化的内容,从目前测试的情况看不单纯有工作流实例的内容,可能还加进去了其他的东东,因为没有学习如何自定义WorkflowPersistenceService,所以这个字段具体保存了那些数据还不清楚。

status:状态,不知道干啥用的,因为我测试的时候他的值一直是0.

unlocked:测试的时候他的值一直是1.

blocked:实例是否被锁定。

info:一直为空,含义未知

ownerID:实例所有者,就是这个实例是被“谁”Load的,是workflowruntime跟当前的应用生成的唯一Id。winform应用 host每次加载后的值都是不同的,如果是wcf或者webservice服务host工作流,只要这些服务不所使用的承载方不重启,那么这个值就是不变 的,一旦重启workflowruntime会生成新的ownerID。

ownedUntil:实例被所有者持有的到期时间,这个值跟SqlWorkflowPersistenceService中的 instanceOwnershipDuration参数有关联,实例被retrieve的时间加上 instanceOwnershipDuration设置的时间就是 ownedUntil的值。

nextTimer:实例失效时间,值一直是9999-12-31 23:59:59,不知道那些动作会影响它。

在workflow项目中一般要进行的操作有:创建工作流,创建工作流实例,加载工作流实例,调用事件。。。。

在创建工作流、实例时, InstanceState表中  blocked为0, ownerID、 ownedUntil都为null;

加载时,blocked为1, ownerID、 ownedUntil都写入了相应的值不为空了;

如果blocked为0, ownerID、 ownedUntil都为null的实例是可以被任何引擎加载的,因为这个状太下没有“人”在使用它。

如果blocked为1, ownerID、 ownedUntil不为null,说明这个实例已经被某个引擎加载并锁定了,这样其他的就不能操作这个实例了,如果您强行调用就会报 System.Workflow.Activities.EventDeliveryFailedException 错, InnerException: System.Workflow.Runtime.QueueException。

如果blocked为1, ownerID、 ownedUntil为null,说明这个已经被重新持久化到数据库,可以被其他引擎使用了。

下回将做测试用的例子整理一下

转载于:https://www.cnblogs.com/SingleCat/archive/2009/12/07/1618319.html