1

分散トランザクションに参加するために、System.EnterpriseServices.ServicedComponentを作成しようとしています。私の主な方法は次のようになります。

public void DoSomething()
{
    try
    {
      // do something useful

      // vote for commit

      if (ContextUtil.IsInTransaction)
          ContextUtil.MyTransactionVote = TransactionVote.Commit;
    }

    catch
    {
      // or shoud I use ContextUtil.SetAbort() instead?

      if (ContextUtil.IsInTransaction)
          ContextUtil.MyTransactionVote = TransactionVote.Abort;

      throw;
    }
}

私がやろうとしているのは、分散トランザクションが中止されたか(またはロールバックされたか)を検出してから、変更のロールバックにも進むことです。たとえば、ディスク上にファイルを作成したり、元に戻す必要のあるいくつかの副作用を実行したりした可能性があります。

SystemTransaction.TransactionCompletedイベントを処理しようとしたか、Dispose()メソッドでSystemTransactionの状態を調べましたが成功しませんでした。

これは「取引」ではなく「補償」に似ていると理解しています。

私がやろうとしていることは意味がありますか?

4

2 に答える 2

1

必要でない限り、そのような方法でトランザクションを管理しないことをお勧めします。

チェーンに関連する他の操作のいずれかが失敗した場合に操作の中止を投票するか、すべてがうまくいった場合にコミットに投票する場合; メソッドの宣言のすぐ上に[AutoComplete]属性 (この記事の備考セクションを参照) を配置するだけです。

このようにして、例外が発生した場合にのみ現在のトランザクションが中止され、それ以外の場合は自動的に完了します。

以下のコードを検討してください (これは典型的なサービス コンポーネント クラスである可能性があります)。

using System.EnterpriseServices;

// Description of this serviced component
[Description("This is dummy serviced component")]
public MyServicedComponent : ServicedComponent, IMyServiceProvider
{
    [AutoComplete]
    public DoSomething()
    {
        try {
            OtherServicedComponent component = new OtherServicedComponent()
            component.DoSomethingElse();

            // All the other invocations involved in the current transaction
            // went fine... let's servicedcomponet vote for commit automatically
            // due to [AutoComplete] attribute
        }
        catch (Exception e)
        {
            // Log the failure and let the exception go
            throw e;
        }
    }
}
于 2012-02-10T23:49:52.503 に答える
0

私自身の質問に答えると、これはSystem.Transactions.IEnlistmentNotificationからも ServicedComponent を派生させることで可能になります。

于 2011-02-28T13:33:32.887 に答える