上一篇中我着重讲了有关工作流持久化的一些相关问题,这篇文章我将讲述活动执行的完整性。及如何设计我们的应用程序界面。
我们的大多数业务数据一般都是用数据库来存储的。想象一下我们在某一个活动中对数据库中的多条数据进行操作,这些数据可能会对下一个活动产生影响;但如果此时活动执行发生意外,我们如何使业务数据和工作流的状态保持一致性?
这里面有几种方面可以使用。
一、将工作流状态数据和业务数据使用同一个数据库,这样就可以在同一个连接中启动事务。这是一个不好的选择,我们很可能需要分离的数据库。且我们的代码必须明确启用事务和SQL语句处理。它所带来的另一个问题是我们无法实现分布式设计,这一点很糟糕。
二、在工作流设计中使用TransactionScope。这是一个不错的选择,不过这个东西应该给是给编程人员用的,而不是最终用户。如果让客户自己去设计工作流,工作人员则需经过一定时间的培训才会使用这种玩意:)。
三、这可能是编程人员最喜欢用的方法,自己去实现IPendingWork接口,用于把对业务数据的处理进行封装,这些业务数据的处理可能来自远程的Web Service。同时我们还需要在引擎中启动WorkflowCommitWorkBatchService服务。 在看SDK文档时我差一点将此处忽略,然而为了数据的完整性,这是至关重要的事情。
我所关心的工作流的另一个重要的事情是:工作流如何影响我们的开发模式,我们如何组织用户界面?这里面的灵活性很高,也没有一个统一的认识,但我却感觉到了这种对传统编程方式的改变。这里我只是讲一下我自己的认识,不枉下结论,还望共同讨论。
根据项目的进展情况可以划分出两种应用。
一、对业务数据的处理已经比较完善,这种情况为了充分利用已有的代码资源,这是的工作流的重点部分在于组织这些业务数据的处理流程。可能用到诸如CodeActivity, ListenAction, CallExternalMethod等活动。这个流程图是开发公司为用户进行定制的,用户无法去自定义这个工作流!
二、要想让用户完全能够自定义工作流程,则给用户看到的必须是自定义的活动,这样用户才能容易将自定义活动和业务活动相联系起来。这样做的一个技术问题就是需要将工作流设计器搬到应用程序中来。至于如何实现请看下面的资源链接。
这里我对于第二种情况进行一下详细的说明。在工作流应用之前,我的应用程序在界面上的布局主要是以数据为核心进行布局的;多个人可能在同一堆数据依据权限和固化的流程进行操作。而引入工作流后,因为流程是不固定的,这就对以前的应用模式构成了挑战:应用程序不关心下一个操作是什么(由引擎导向),只有一种提交与否的状态选择。也就是说一个工作人员不需要从界面中选择合适的数据并明确地指出将把数据置入一个什么样的处理流程中。情况变得好像简单多了,他可以直接看到他要处理的数据,并做出处理结果便可以了。
由于引入工作流后,每个工作人员的操作模式被统一起来:进入应用程序后直接显示要处理的数据,做完处理后提交。所以我们有理由将用户的这种界面进行统一起来,我们只关心业务数据的处理,而不关心业务数据的流程!为此我们在自定义活动中加入一个人员列表,这样用户管理员在工作流自定义时便可指定可对该活动进行操作的人员列表。每个工作人员在登录后只列出能够操作的活动列表。选择一个活动便可进入工作状态。这样的感觉很好。
为了实现这样的功能我们还要做一些文章,工作人员为了进行处理,还需要和工作流进行交互,这里我们需要一个EventDriven吗?,如果用的话我们的自定义活动将变得很复杂,或者根本就不能用;如果不用的话,工作人员如何告诉工作流处理的结果呢(应用程序和工作流实例工作于两个独立的线程中)。有一种方法那就是用ManualWorkflowSchedulerService服务,这样可以使工作流引擎和应用程序位于同一线程之内运行。或许有更好的法子,请不要忘记告诉我。
还有件事情得做,给每一个自定义活动打上一个PersistOnCloseAttribute属性。很重要,我们需要有一个机会让工作流停下来,PersistOnCloseAttribute是一个不错的选择。
用户中的管理员可能经常改变流程处理,做一个版本记录吧,不要直接修改已经运行着的工作流实例!(不是不能修改运行的工作流实例,但不建议这样做)。这样已经运行的用老的版本,对于新建的工作流用新的工作流设计。两者都运行的很好,何乐而不为呢。
差不多了,先写这些吧。希望对大家有帮助。
有关工作流的文章请参考下面我写的文章。
WWF的一些技术细节与应用体会(一)
Rehosting WWF 设计器 之运行时定制活动的外观
Rehosting WWF Designer 之定制活动的外观
Rehosting WWF Designerp之从工具箱拖动活动到设计器上
Rehosting WWF 设计器