3

最近、WFでExternalDataExchangeベースの通信をいくつか使用しています。私の理解では、長時間実行される (この場合はステート マシン) ワークフローを使用する場合、通信はキューに入れられ、耐久性があり、トランザクションです。

SQL Persistence と、「WaitForIdle = true」とマークされた EventArgs を使用しています。

私は次のようなことをすると思います:

using(TransactionScope scope = new TransactionScope())
{
     IMyEDEService service = wfRuntime.GetService<IMyEDEService>()
     service.MyMethod(wfInstanceGuid, "Here's some data");
     DoSomeDatabaseWork();
} //Dispose causes scope to rollback

ワークフローでイベントが発生しないことが予想されます。ただし、実際には配信されているように見えるので、これはトランザクションではないと思います。DoSomeDatabaseWork() でデータベースにコミットされたデータがどのようにロールバックされるかを確認できましたが、前に進むワークフローがうまくいかない可能性があります。

誰でもこれを確認できますか? もしそうなら、メッセージをトランザクション化するための回避策はありますか?

本当に欲しいのは、次の2つのいずれかです。

  1. ワークフローは、メッセージをエンキューしたトランザクションがコミットされるまで、外部データ交換を介してエンキューしたメッセージに反応するべきではありません (SQL サーバーでサービス ブローカーが行うのと同じように)。

- また -

  1. 配信したイベントに対してワークフローが動作を開始した場合は、ロールバックも行う必要があります。ただし、デフォルトのスケジューラを使用してこれがどのように発生するかはわかりません。ワークフローの実行を非同期のままにしたいので、必要がなければスケジューラーを切り替えたくありません。
4

1 に答える 1

2

ここでいくつかの問題が発生しています。まず、SQL 永続性を使用している場合、ワークフローにイベントを通知し、ワークフローにイベントを発行させることは永続的かつ非同期であり、ワークフローの基盤となる配管はトランザクションです...しかし、あなたが考える方法ではありません。

一連のイベントのどこかで恐ろしいことが発生し、最終的にワークフローが新しい状態に移行した場合、ワークフローはアクティビティを試行する前の状態に戻ります。これにより、ワークフローは「州間」は悪い考えです。

上記のようにトランザクション スコープを使用しても問題ありませんが、トランザクション スコープが実際に機能するのは、using ブロック内のクラスがトランザクション スコープを認識している場合のみであることを覚えておく必要があります。

できることは、「MyMethod」への呼び出しを try/catch ブロックでラップすることです。何か問題が発生した場合は、ロールバックに投票できますが、それでも EDES でメソッドを「呼び出し解除」することはできません。

より高いレベルで達成しようとしていることについて具体的に説明できる場合は、トランザクション スコープをミックスに押し込むよりも、WF に固有のものがいくつかある可能性があります。

編集

掘り下げてみたところ、スケジューラのワーク キューを操作する API がないと言われている場所がいくつか見つかりました。残念ながら、これが意味することは、私たちが望むどんな種類のロールバック動作も、自分で手動で実装する必要があるということです。

EDES を介してキューに入れられた作業をロールバックしようとしている理由について詳しく知っていれば、車輪 (トランザクション) を再発明することなくタスクを達成するための潜在的なアーキテクチャをいくつか提案できるかもしれません。

このような問題に遭遇した場合、10 回中 9 回は、WF が私がやろうとしていることをサポートしていないように見えます。問題は、ワークフローのにあまりにも多くのコードを保持しているか、配置しようとしたためです。そこに多くのコード追加し、作業が完了した場所をリファクタリングすることで、新しいものを書かなくても問題が解決することがよくあります。

于 2009-04-14T13:35:31.527 に答える