ロールバックは大変です - 私の知る限り、実際には 2 つの方法しかありません。2 フェーズ コミット プロトコル、または補正トランザクションのいずれか。これらの方法のいずれかでタスクを構成する方法を見つける必要があります。
通常、より良いアイデアは、他の人々の努力を利用し、既に 2PC または補償が組み込まれているテクノロジを使用することです。これが、RDBMS が非常に人気がある理由の 1 つです。
したがって、詳細はタスクに依存します...しかし、パターンはかなり簡単です:
class Compensator {
Action Action { get; set; }
Action Compensate { get; set; }
}
Queue<Compensator> actions = new Queue<Compensator>(new Compensator[] {
new Compensator(SendEmail, UndoSendEmail),
new Compensator(ArchiveReportsInDatabase, UndoArchiveReportsInDatabase),
new Compensator(CreateAFile, UndoCreateAFile)
});
Queue<Compensator> doneActions = new Queue<Compensator>();
while (var c = actions.Dequeue() != null) {
try {
c.Action();
doneActions.Add(c);
} catch {
try {
doneActions.Each(d => d.Compensate());
} catch (EXception ex) {
throw new OhCrapException("Couldn't rollback", doneActions, ex);
}
throw;
}
}
もちろん、特定のタスクについては、運がいいかもしれません。
- 明らかに、RDBMS の作業は既にトランザクションにラップできます。
- Vista または Server 2008 を使用している場合は、トランザクション NTFSで CreateFile シナリオをカバーできます。
- 電子メールは少しトリッキーです - 私は2PCや Compensator については知りません (ただし、誰かが Exchange にあると指摘しても少し驚くだけです) 。サブスクライバーがそれを受け取り、最終的にメールで送信します。その時点で、トランザクションはメッセージをキューに送信するだけで済みますが、おそらくそれで十分です。
これらはすべてSystem.Transactionsトランザクションに参加できるので、かなり良い状態になっているはずです。