9

電子メールを送信し、ファイルに書き込み、Web サービスを呼び出す必要があります。一貫性を維持するには、すべてのステップを実行する必要があります。いずれかのステップで例外またはエラーがスローされた場合、すべてのステップをロールバックする必要があります。

独自のオブジェクト ACID エンジンを展開する前に、オブジェクト レベルで ACID セマンティクスを実装するための一般的に受け入れられているパターンはありますか?

さらに良いことに、.NET プラットフォームで使用できる既存のライブラリはありますか?

編集:電子メールの送信を元に戻せないことは知っていますが、SMTP サーバーへの接続に失敗すると、トランザクション全体が強制終了されます。また、将来のアクションで使用できるように拡張できるようにしたいと考えています。

4

7 に答える 7

5

このようなものを最後に見たのは数年前です。少し覚えているのは、コマンド パターンを使用し、各コマンド オブジェクトをキューに格納していたことです。LIFOスタックだったと思います。

そのため、「トランザクション」が失敗した場合、エンジンはコマンド オブジェクトをポップオフし、コマンドを元に戻し、コマンド オブジェクトを破棄します。スタックが空になるまで繰り返します。「トランザクション」が成功した場合、スタックはクリアされました。

残念ながら、それ以上のことは覚えていません。

CSLA.NETは、同様の取り消しスタックを実装しています。これは、頭のてっぺんから考えることができるコードの唯一の例です。

于 2009-02-24T03:35:50.300 に答える
3

Windows Workflow Foundation には、ACID セマンティクスが適切でない場合に (複合アクティビティを使用して)補正するという概念があります。もちろん、ACID トランザクションもサポートしています。

良い質問は、なぜわざわざ補償をするのかということです。自動ロールバックを伴う 1 つの大きな ACID トランザクションも同様に優れているのではないでしょうか? ACID トランザクションは、操作が同じデータベース内または同じ情報システム内で発生する場合に最適です。また、操作がすぐに終了する場合にも最適です。さまざまな企業やサービスが関与している場合、ACID セマンティクスの観点からプロセスを定義することは、多くの場合困難です。分離して耐久性を持たせるには、タスクの期間中、さまざまな会社のすべてのリソースをロックしておく必要があります。特にタスクが長い場合、これはしばしば不合理です。一貫性がありアトミックであるためには、アドホックな補正コードが必要です。

于 2009-02-24T03:18:56.533 に答える
3

The simplest technique without relying heavily on an external library is prevalence. Periodically checkpoint by using serialization to take a snapshot of your state, then maintain a journal by serializing enough information on every side-effectful operation against your data to repeat it later. If something blows up, reload the most recent checkpoint, then re-apply all journal records written after that point.

For something more sophisticated, try software transactional memory. It may be somewhat clumsy to implement in current languages, but is quite powerful and may give you some additional concurrency techniques as well.

For irreversible operations like accessing a Web service or sending an email, you'll need to use compensating transactions: make another Web service call to cancel or update the results of the previous one, or perhaps send another email advising the recipient that things didn't work as intended.

于 2009-02-24T03:49:11.547 に答える
1

1 つのアイデアは、JMS を「エンジン」として使用することです。JMS トランザクションを利用できます (DB トランザクションなどの既存のトランザクションに参加できます)。これは、単純なアプリについて話している場合を除き、おそらく良いことである非同期イベント駆動型アーキテクチャにつながり始めます。その場合、おそらく質問する必要はありません。

この例は、単純なアカウントの作成です。このために、アカウント情報を DB に保持し、アクティブ化のためにユーザーに電子メールを送信する必要がありますが、明らかな理由から、それらを同じトランザクションに含める必要があります。

電子メールを送信しても - db トランザクション コミットが何らかの理由で失敗する可能性があるため、電子メール送信コードをトランザクション内に配置しないでください。また、電子メール送信が失敗して孤立したアカウントになる可能性があるため、電子メール送信を (コミット後に) トランザクションの外に置くべきではありません。

したがって、このシナリオで JMS を使用するには、JMS 送信コードを DB トランザクション内に配置し、そのトランザクションに参加させます。メッセージの配信が保証されます。反対側では、メールを送信するキューを消費する何かがあります。電子メールの送信に失敗した場合は、ログに記録してアラートを生成するのが最善の方法です。JMS はロールバックし、メッセージをキューに戻して後で消費できるようにします。つまり、問題が何であれ、うまくいけば修正されたら、電子メールを再送信してみてください。

重要なことは、DB レコードが一貫しており、電子メールが最終的に送信されることです。

于 2009-08-18T14:54:03.813 に答える
1

電子メールの送信を取り消すことはできず、ファイルを書き込むのは比較的安価であるため、適切な順序でこれらのことを行うだけです。

  1. ファイルの書き込み/ファイルの書き込みを試みます。失敗した場合は停止し、そうでない場合は続行します。
  2. Web サービスを呼び出します。失敗した場合は、ファイルを削除して停止します。それ以外の場合は、次の手順に進みます。
  3. Send e-mail -- email is asynchronous anyhow, so you'd never really know if it was sent or not since most e-mail servers are set to retry for a couple of days if an error occurs and you never get back an acknowledgment that the e-mail went through even if it was successful.
于 2009-02-24T03:48:26.497 に答える
0

また、実験的なプロジェクトSTM .NETが最近リリースされました。このプロジェクトは、C# にトランザクション メモリを追加します。実際には、これをサポートするために CLR を変更します。

于 2009-08-18T14:58:33.820 に答える
0

2つの考え:

于 2009-02-24T04:07:21.083 に答える