WF4中的持久化模型有了很大的变化。

SqlWorkflowInstanceStore是WF提供给我们的开箱即用的类,它会将工作流数据保存到SQL Server 2005或是2008中。该类从InstanceStore类继承,
如果你要实现自己的持久性功能就需要实现该类的子类。

我们可以用SqlWorkflowInstanceStore来做什么?

我们可以将它附加到一个WorkflowApplication或一个WorkflowServiceHost上,在我们需要的时候来持久化工作流。注意WorkflowInvoker是不支持持久化的。

下面是在WorkflowApplication中使用的例子:

var instanceStore = new SqlWorkflowInstanceStore(connStr);

WorkflowApplication app = new WorkflowApplication(workflow);

app.InstanceStore = instanceStore;

app.Run();

首先你需要存储工作流状态的数据库,在

“C:\Windows\Microsoft.NET\Framework\v4.0.21006\SQL\en”文件夹下有一些SQL文件,SqlWorkflowInstanceStoreSchema.sql 和SqlWorkflowInstanceStoreLogic.sql持久化需要的,可以创建了一个批处理文件来快速重新创建数据库,如下:

osql -E -S .\sqlexpress -Q "Drop Database WorkflowInstanceStore"

osql -E -S .\sqlexpress -Q "Create Database WorkflowInstanceStore"

osql -E -S .\sqlexpress -d WorkflowInstanceStore -i SqlWorkflowInstanceStoreSchema.sql

osql -E -S .\sqlexpress -d WorkflowInstanceStore -i SqlWorkflowInstanceStoreLogic.sql

我们需要告诉WorkflowApplication什么时候持久化工作流,有很多种方式可以使用,其中一种就是使用PersistableIdle回调函数,它在工作流Idle并且允许持久化时激发。我们可以持久化并卸载工作流,也可以只卸载工作流。如下:
app.PersistableIdle = e => PersistableIdleAction.Persist;

还有一种方式就是使用Persist活动,他可以允许在其他的持久化点来持久化工作流,不管工作流是否处于Idle状态。

在WorkflowServiceHost中如何使用?

在WorkflowServiceHost中使用有一些不同,首先创建一个SqlWorkflowInstanceStore 实例,并设置如下:

var workflow = new Workflow1();

var baseAddress = new Uri("http://localhost:8080/MyWorkflow");

var host = new WorkflowServiceHost(workflow, baseAddress);

var connStr = @"Data Source=.\sqlexpress;Initial Catalog=WorkflowInstanceStore;Integrated Security=True;Pooling=False";

var instanceStore = new SqlWorkflowInstanceStore(connStr);

host.DurableInstancingOptions.InstanceStore = instanceStore;

host.Open();

Console.WriteLine("Listening...");

Console.ReadLine();

host.Close();

代码很简单,但是当工作流持久化时我们不能做任何的控制,能做的仅仅是使用WorkflowIdleBehavior来设置一些timeout的值如下:

var workflowIdleBehavior = new WorkflowIdleBehavior();

workflowIdleBehavior.TimeToPersist = TimeSpan.FromSeconds(10);

workflowIdleBehavior.TimeToUnload = TimeSpan.FromMinutes(1);

host.Description.Behaviors.Add(workflowIdleBehavior);

如果我们想要通过一些方式对SqlWorkflowInstanceStore行为进行更多的控制。我们可以使用SqlWorkflowInstanceStoreBehavior。下面使用类的方式也可以通过配置文件完成:

var connStr = @"Data Source=.\sqlexpress;Initial Catalog=WorkflowInstanceStore;Integrated Security=True;Pooling=False";

var behavior = new SqlWorkflowInstanceStoreBehavior(connStr);

behavior.InstanceCompletionAction = InstanceCompletionAction.DeleteNothing;

behavior.InstanceLockedExceptionAction = InstanceLockedExceptionAction.AggressiveRetry;

behavior.InstanceEncodingOption = InstanceEncodingOption.None;

host.Description.Behaviors.Add(behavior);

当多个 WorkflowApplication 实例中使用相同的 SqlWorkflowInstanceStore时会有一些复杂。不过在WorkflowServiceHost中会自动负责处理这种情况。

默认情况下一个SqlWorkflowInstanceStore 将只使用一个单一的 WorkflowApplication。如果您尝试与多个工作流使用,你会得到一个InstancePersistenceCommandException 异常,如下:

SqlWorkflowInstanceStore does not support creating more than one lock owner concurrently. Consider setting InstanceStore.DefaultInstanceOwner to share the store among many applications.

从上面的信息可以看出,技巧就是要设置SqlWorkflowInstanceStore的

DefaultInstanceOwner属性,如下:

var instanceStore = new SqlWorkflowInstanceStore(connStr);

var instanceHandle = instanceStore.CreateInstanceHandle();

var createOwnerCmd = new CreateWorkflowOwnerCommand();

var view = instanceStore.Execute(instanceHandle, createOwnerCmd, TimeSpan.FromSeconds(30));

instanceStore.DefaultInstanceOwner = view.InstanceOwner;

// Do whatever needs to be dome with multiple WorkflowApplications

var deleteOwnerCmd = new DeleteWorkflowOwnerCommand();

instanceStore.Execute(instanceHandle, deleteOwnerCmd, TimeSpan.FromSeconds(30));

关键是要在开始时执行所需的CreateWorkflowOwnerCommand,当您使用 CreateWorkflowOwnerCommand 时要确保不能忘记最后执行

DeleteWorkflowOwnerCommand ,否则所有工作流让然还被所有者锁定,不能重新加载另一个 SqlWorkflowInstanceStore。

可以看出,WF4中的持久性比以前更灵活。

译者注:

1.       Beta2中使用SqlWorkflowInstanceStore 和 InstanceStore 取代了Beta1中的

SqlPersistenceProviderFactory 和 PersistenceProviderFactory。

2. PersistableIdleAction枚举有三个值:None,Unload,Persist。

作者:生鱼片

    

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 
 

workflow4.0持久化的更多相关文章

  1. workflow4.0学习资料

    http://www.cnblogs.com/foundation/archive/2010/04/03/1703809.html 2篇说明: WF4 Bata 2 WF4.0 RC 对比 Beta2 ...

  2. Redis(5.0.0)持久化AOF和 RDB 结合源码分析

    主要是挖个坑.候补(代码还没看完..) https://github.com/antirez/redis/tree/5.0 一.Redis保存持久化文件 二.Redis启动加载持久化文件 src/se ...

  3. Nacos 配置MySQL8.0持久化

    问题描述 官网下载的Nacos mysql由于驱动过低只支持5.X版本,使用8.X版本的mysql时无法正常启动 解决办法 克隆nacos源码(branch 1.0.0-RC3) master等分支也 ...

  4. Redis 持久化深入--机制、可靠性及比较

    本文是对 antirez 博客中 Redis persistence demystified 的翻译和总结.主要从Redis的持久化机制,提供何种程度的可靠性以及与其他数据库的比较三个方面进行讨论. ...

  5. JDO持久 (jdbc ejb)

    转自:http://blog.csdn.net/liuzhigang1237/article/details/6305113 JDO快速入门 Java数据对象(Java Data Objects,JD ...

  6. JPA OpenJPA 简单例子

    JPA 全称,Java Persistence API,Java持久化API JPA是一套持久化标准,相当于JDBC标准,针对于此标准的实现目前有OpenJAP,TOPLINK,Hibernate等. ...

  7. hadoop默认3个核心配置文件说明

    1       获取默认配置 配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapred-site.xml三个配置文件,默认下来,这些配置文件都是空的,所以很难知 ...

  8. EJB(一)认识ejb

    什么是ejb? 相同仍旧在这个系列博客之处,谈谈对ejb的认识和理解.         sun微公司对于ejb的定义大体是这种,ejb是一套用于开发和部署分布式组件的的架构.採用ejb的架构应用能够是 ...

  9. hadoop三个配置文件的参数含义说明core-site.xml,hdfs-site.xml,mapred-site.xml

    配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapred-site.xml三个配置文件,默认下来,这些配置文件都是空的,所以很难知道这些配置文件有哪些配置可以生 ...

随机推荐

  1. Html5新增的语义化标签(部分)

    2014年10月29日,万维网联盟宣布,经过接近8年的艰苦努力,html5的标准规范终于制定完成.这是互联网的一次重大变革,这也许是一个时代的来临! 总结一些h5新增的语义化标签,记录下来方便自己学习 ...

  2. power desinger 学习笔记<八>

    转-PowerDesigner 把Comment复制到name中和把name复制到Comment 在使用PowerDesigner对数据库进行概念模型和物理模型设计时,一般在NAME或Comment中 ...

  3. 用java写bp神经网络(四)

    接上篇. 在(一)和(二)中,程序的体系是Net,Propagation,Trainer,Learner,DataProvider.这篇重构这个体系. Net 首先是Net,在上篇重新定义了激活函数和 ...

  4. ios里面如何压缩图片

    在iOS里面,压缩图片跟在其他环境里面差不多,都和累死, 就是对当前图片从新画图,制定一个尺寸的问题 UIImage* image = [UIImage imageNamed:@"cat.j ...

  5. jQuery实现页面元素智能定位

    实现过程 Js侦听滚动事件,当页面滚动的距离(页面滚动的高度)超出了对象(要滚动的层)距离页面顶部的高度,即要滚动的层到达了浏览器窗口上边缘时,立即将对象定位属性position值改成fixed(固定 ...

  6. javascript的选项卡

    主要用的索引值 首先 写三个按钮 <input type="button" > <input type="button" > <i ...

  7. JavaScript中style.left与offsetLeft的区别

    今天在制作焦点轮播图的时候,遇到一个问题,在使用style.left获取图片的位置时,怎么也获取不到.换用offsetLeft就能够成功获取到了.虽然实现了我想要的效果,但是还是不甘心啊,没有找到原因 ...

  8. html5系列.基础知识

    兼容性问题 创建一个html5页面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...

  9. jquery 实现的一款超简单的图片切换功能

    <html><head> <meta http-equiv="Content-Type" content="text/html; chars ...

  10. SQL Server 连接字符串和身份验证

    SQL Server .NET Data Provider 连接字符串包含一个由一些属性名/值对组成的集合.每一个属性/值对都由分号隔开.         PropertyName1=Value1;P ...