次のコードを使用して、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 であるスコープにアクセスできます。検査できる物件はほとんどありません。
失敗したか成功したかを判断する方法はありますか?