WWF Persist Serviceのサンプル

WWFのHelpに含まれているサンプルには、お宝が一杯詰まっているようです。
今回はワークフローインスタンスの永続化のサンプルを見つけたので紹介します。

Persist Service Sample
WWF Help > Windows Workflow Foundation Samples > Technology Samples
  > Hosting > Using Persistence Services

1. SQL Server上にデータベースを二つ作成
サンプルを実行するには、事前にデータベースを二つ作成する必要があります。
スキーマとストアドプロシージャは下記フォルダにSQLファイルが含まれています。

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\Windows Workflow Foundation\SQL

WorkflowStore
ワークフローインスタンスのステータスが記録されるデータベースです。
データベースは「WorkflowStore」の名前で手動で作成します。
スキーマ作成は「SqlPersistenceService_Schema.sql」ファイルを
ストプロ作成は「SqlPersistenceService_Logic.sql」ファイルを実行します。

TimerStore
ワークフローをいつ起動するかのタイマーの情報が記録されるデータベースです。
データベースは「TimerStore」の名前で手動で作成します。
スキーマ作成は「SqlTimerService_Schema.sql」ファイルを
ストプロ作成は「SqlTimerService_Logic.sql」ファイルを実行します。

2. サンプル実行
データベースを作成しておけば、サンプルを動かすことができます。
問題があるとすれば認証関連のとこだけでしょう。
サンプルは以下の図のようなワークフローを実行します。

サンプルを実行すると、遅延(Delay)アクティビティが実行された段階で、
データベースに永続化されることが確認できます。
ブレークポイントを設定して、データベースにレコードができることを確認してみてください。
ワークフローが完了したら、レコードは削除されてしまいます。

3. サンプルコードの確認
大事なポイントは、ワークフローを起動しているコードにあります。
サンプルのProgram.csファイルを確認してみます。

WorkflowRuntime workflowRuntime = new WorkflowRuntime();

workflowRuntime.AddService(new SqlStatePersistenceService("Initial Catalog=WorkflowStore;Data Source=localhost;Integrated Security=SSPI;"));
workflowRuntime.AddService(new SqlTimerService("Initial Catalog=TimerStore;Data Source=localhost;Integrated Security=SSPI;"));

workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(OnWorkflowCompleted);
workflowRuntime.WorkflowIdled += new EventHandler<WorkflowEventArgs>(OnWorkflowIdled);
workflowRuntime.WorkflowPersisted += new EventHandler<WorkflowEventArgs>(OnWorkflowPersisted);
workflowRuntime.WorkflowUnloaded += new EventHandler<WorkflowEventArgs>(OnWorkflowUnloaded);
workflowRuntime.WorkflowLoaded += new EventHandler<WorkflowEventArgs>(OnWorkflowLoaded);
workflowRuntime.WorkflowTerminated += new EventHandler<WorkflowTerminatedEventArgs>(OnWorkflowTerminated);

Type type = typeof(UsingPersistenceServices);

workflowRuntime.StartWorkflow(type);

永続化サービスとタイマーサービスを追加しているところと、
イベントによって結びついているところがここでのポイントですね。
素敵なコードです、これ。

ワークフローのインスタンスを永続化できるのは非常に意味があります。
何故かというと、B2BのシナリオなどでWWFを使用する場合、
2つの企業間でメッセージのやり取りをしている最中の状態を永続化することで、
もし障害が発生した場合もリカバリがきくようになります。
つまり信頼性の向上につながるからです。
またロングトランザクション機能を使う際も、この永続化は必須になるようです。

BizTalkのオーケストレーションは永続化の機能が組み込まれていたため、
逆に「軽く」使うことができなかったのですが、さすがにWWFでは洗練されていますね。

外部から明示的に永続化、永続化したワークフローのインスタンスを起動できるかは
今後調査していきたいと思います。