私はSystem.Transactionsの機能を知ることができるように、すばやいダミーアプリを作ろうとしています。このアプリケーションは、2つの異なるSQLExpress DBと対話します。コンポーネントサービスでトランザクション統計を取得すると、2番目の接続が開かれたときにouterScopeでトランザクションが開始されます。 failOuterがtrueの場合、トランザクションはアボートされますが、例外はスローされません。 failInnerがtrueの場合、TransactionAbortedExceptionがスローされます。 MSDNからTransactionScopeを理解しようとしています
:
アプリケーションは、それがトランザクションで実行したいすべての作業を完了したら、あなたはトランザクションのコミットを受け入れ可能であることをトランザクションマネージャに通知するために、一度だけ完全なメソッドを呼び出す必要があります。 usingブロックの最後のステートメントとしてCompleteを呼び出すことは、非常に良い習慣です。
このメソッドの呼び出しに失敗すると、トランザクションマネージャーはこれをシステム障害、またはトランザクションのスコープ内でスローされた例外と解釈するため、トランザクションを中止します。
スコープがトランザクションを作成し、トランザクションがアボートされると、TransactionAbortedExceptionがスローされます。私は私のトランザクション統計は毎回中止されたトランザクションを示しているので、私はfailOuterと私のアプリをtrueに設定し実行する私のouterScopeがTransactionAbortedExceptionを投げることを期待することに基づいて
。トランザクションが中断しても例外がスローされないので、私のメソッドはtrueを返します。私が内部取引を中止しない限り、それは私が期待するように動作します。どのような明確化が最も高く評価されるだろう。
public bool CreateNestedTransaction(bool failOuter, bool failInner)
{
try
{
using (TransactionScope outerScope = new TransactionScope())
{
/* Perform transactional work here */
using (SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=test1"))
{
SqlCommand myCommand = new SqlCommand();
myConnection.Open();
myCommand.Connection = myConnection;
myCommand.CommandText = "update test set Value = ((select Value from test where Id = (select max(Id) from test))+1) where Id = (select max(Id) from test)";
myCommand.ExecuteNonQuery();
}
using (SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=test1"))
{
SqlCommand myCommand = new SqlCommand();
myConnection.Open();
myCommand.Connection = myConnection;
myCommand.CommandText = "update test set Value = Value";
myCommand.ExecuteNonQuery();
}
using (TransactionScope innerScope = new TransactionScope())
{
using (SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=test2"))
{
SqlCommand myCommand = new SqlCommand();
myConnection.Open();
myCommand.Connection = myConnection;
myCommand.CommandText = "update test set Value = ((select Value from test where Id = (select max(Id) from test))+1) where Id = (select max(Id) from test)";
myCommand.ExecuteNonQuery();
}
if (failInner == false) { innerScope.Complete(); }
}
if (failOuter == false) { outerScope.Complete(); }
}
}
catch (TransactionAbortedException)
{
return false;
}
return true;
}
はい、意味があります。私はMSDNの最後の行が私を捨てていたと思う。トランザクションが中止され、例外が発生するのを見ていました。説明ありがとう!私の外側の例外が異常終了したかどうかを知る方法はありますか?私はその場合にfalseを返す。 –
Hmm興味深い質問 - わからない!私は家に帰って、あなたに知らせるときにそれをチェックします:) –
はい、それは私が一般的に使用するパターンではありませんが、それを行う方法があるように見えます。 –