2013-04-18 17 views
5

以下の方法を検討してください。明示的に完了するまで、TransactionScopeは暗黙的に適用されますか?

DoA() 
{ 
    using (TransactionScope scope = new TransactionScope) 
    { 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     connection.Open(); 
     SqlCommand command = new SqlCommand(query, connection); 
     command.ExecuteNonReader(); 

     DoB();  

     scope.Complete(); 
    } 
    } 
} 

DoB() 
{ 
    using (TransactionScope scope = new TransactionScope) 
    { 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     connection.Open(); 
     SqlCommand command = new SqlCommand(query, connection); 
     command.ExecuteNonReader(); 

     DoC(); 

     scope.Complete(); 
    } 
    } 
} 

DoC() 
{ 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
    connection.Open(); 
    SqlCommand command = new SqlCommand(query, connection); 
    command.ExecuteNonReader(); 
    } 
} 

我々はDoA()を呼び出す場合は、SQL Serverに関連するとして、DoA()のトランザクションのコンテキストでDoB()DoC()の実行で、その後の相互作用を行いますか? DoC()はDoA()DoB()の両方のトランザクションのコンテキストで実行されますか?

(それとも私が何かを誤解ひどくだ?)アンディのコメント当たりに編集

+1

ネストされたトランザクションを取得します:) – DaveShaw

+0

これを制御するオプションがあります。 http://msdn.microsoft.com/en-us/library/ms172152(v=vs.85).aspxの「TransactionScopeOptionを使用したトランザクションフローの管理」を参照してください。 – AaronLS

+0

ネストされたトランザクションに関するさらに詳しい説明は、環境トランザクションに参加する。 – AaronLS

答えて

4

すべてのコードは論理的に1つのトランザクションになります。ネストされたスコープは(RequiresNewを使用しない限り)必ずしも新しいトランザクションを作成するとは限りません。したがって、単一のトランザクションになります。今度は、Completeを削除すると、2番目のスコープでトランザクションを完了するために各スコープが投票しなければならないため、トランザクション全体がロールバックされるはずです。

DoCもトランザクションの一部になります。アンビエントトランザクションは新しい接続を検出し、自動的に登録されます。

周囲取引と異なるオプションRequiresRequiresNew、およびSuppressに入学の動作を説明する詳細hereのすべてをお読みください。

接続でEXACTLYの同じ接続文字列を使用しないと、トランザクション全体が自動的に分散トランザクションに昇格します。気を付けるだけのこと。

+0

+1良い情報。受け入れる前に 'DoA()'や 'DoB()'の 'Transaction'の中で' DoC() 'が実行されていることを確認できますか? (これは私が*期待している*と思う*は起こりますが、確信しています) – svidgen

+0

@svidgen私の答えを更新しました。 – Andy

+0

美しい。ありがとう! – svidgen

2

:このような何かが、SQLサーバー上で発生するかのように

に思える:

BEGIN TRANSACTION A 

    -- do A's work 

    -- B does NOT create a new transaction 

    -- do B's work 

    -- do C's work 

COMMIT TRANSACTION A 

以下が発生しましたDoB()new TransactionScope(TransactionScopeOption.RequiresNew)が使用されている場合。

BEGIN TRANSACTION A 

    -- do A's work 

    BEING TRANSACTION B 

    -- do B's work 

    -- do C's work 

    COMMIT TRANSACTION B 
COMMIT TRANSACTION A 
+0

これは起こることではありません。 Bで使用されるスコープが既存のアンビエントトランザクションに参加するため、単一のトランザクションになります。 Bが「Complete」に投票しなかった場合、トランザクション全体がロールバックされます。 – Andy

+0

@Andy説明をありがとう。 'new TransactionScope(TransactionScopeOptions.RequiresNew)'を代わりに使用すると、これは起こりますか? – svidgen

+0

@Andy Nevermind、ちょうどあなたの答えを見た! – svidgen

関連する問題