質問

分散トランザクションに参加するために、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()メソッドのシステムトランザクションの状態を検査しようとしました。

これは、「トランザクション」ではなく「補償」に似ていることを理解しています。

私がやろうとしていることは理にかなっていますか?

役に立ちましたか?

解決 2

私自身の質問に答えると、これはサービスコンポーネントをから導き出すことによって可能です system.transactions.ienlistmentnotification 同じように。

他のヒント

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

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

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

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

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;
        }
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top