平庸与杰出=加法与减法

思考其乐无穷 IT剩者为王

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
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,说明这个已经被重新持久化到数据库,可以被其他引擎使用了。

下回将做测试用的例子整理一下
posted on 2007-11-30 14:55  我是蚂蚁  阅读(4490)  评论(7编辑  收藏  举报