0

次のコードを使用して、Castle ActiveRecord v1.0.3 (レガシー!) を使用して削除操作を実行しています。

public void Delete(anObject instance)
{
    try
    {
        using (var scope = new ActiveRecord.TransactionScope(TransactionMode.Inherits, OnDispose.Rollback))
        {
            ...(DB Operations)

            scope.VoteCommit();

            MethodCallBecauseOfSuccess();
        }
    }
    catch (NHibernate.TransactionException ex)
    {
        MethodCallBecauseOfFailure();
    }
}

問題は、TransactionMode.Inherits が原因で、このメソッドのコンシューマが、このメソッドへの呼び出しを独自の ActiveRecord.TransactionScope にラップできることです。これを行う場合、scope.VoteCommit() の時点で例外が発生しないため、MethodCallBecauseOfSuccess() が誤って呼び出されます。

これは私が使用しているレガシー コードであるため、この時点で消費コードを再加工することはできません。このメソッドを変更することしかできません。

そのため、TransactionScope.OnTransactionCompleted イベントを調べているので、トランザクション スコープが呼び出し元のメソッドに消えた場合でも、完了時にトラップして、適切なメソッドを呼び出すことができます。たとえば、次のようになります。

public void Delete(anObject instance)
{
    try
    {
        using (var scope = new TransactionScope(TransactionMode.Inherits, OnDispose.Rollback))
        {
            scope.OnTransactionCompleted += (sender, args) => 
                                        {
                                            //if FAIL
                                            MethodCallBecauseOfFailure();
                                            //else SUCCEED
                                            MethodCallBecauseOfSuccess();
                                        };

            ...(DB Operations)

            scope.VoteCommit();
        }
    }
    catch (NHibernate.TransactionException ex)
    {
        ...     
    }
}

残念ながら、TransactionScope が失敗したか成功したかを判断できないようです。匿名メソッドのパラメーターは、送信者 = 親 (だと思います!) トランザクション スコープ、および args = 空です。そしてもちろん、現在の TransactionScope であるスコープにアクセスできます。検査できる物件はほとんどありません。

失敗したか成功したかを判断する方法はありますか?

4

1 に答える 1

0

プロパティ HasSessionError は役に立ちますか?

try
{
    using (TransactionScope scope = new TransactionScope(TransactionMode.Inherits, OnDispose.Rollback))
    {
        scope.OnTransactionCompleted += (sender, args) => 
                                    {
                                        TransactionScope sender2 = (TransactionScope)sender;
                                        if(sender2.HasSessionError)
                                          MethodCallBecauseOfFailure();
                                        else
                                          MethodCallBecauseOfSuccess();
                                    };

        ...(DB Operations)

        scope.VoteCommit();
    }
}
catch (NHibernate.TransactionException ex)
{
    ...     
}

ご挨拶

ジュイ・ジュカ

于 2012-08-15T02:37:09.170 に答える