2011-08-08 9 views
7

これに相当する方法を実行するにはどうすればよいですか? My understanding is that this is impossible with TransactionScopesしかし、私はいくつかの他の方法で同等のものを達成したいと思います:.NET内のネストされたトランザクション

ビジネスロジッククラス:私はトランザクションのこの内部のすべての(おそらく統合テストをカプセル化するまで

public bool Bar() 
{ 
    try 
    { 
    using (var tsWork = new TransactionScope()) 
    { 
     ComplicatedDataImportCode(somedata); 
     FlagRecordInDatabaseAsImported(); // this is the same record that's modified in the catch 
     tsWork.Complete(); 
     return true; 
    } 
    catch (DuplicateDataException err) 
    { 
     // if we got here, the above transaction should have rolled back, 
     // so take that same record in the database and update it to "Duplicate". 
     FlagSameRecordInDatabaseAsDuplicate(err.Message); 
    } 

    return false; 
} 

さて、これは、正常に動作しますアサートを実行した後にロールバックしたい)。私のポイントを証明する

簡単なテスト:最終的には、Foo.Bar()のコードはしかし、ソリューションに対応するために変更することができ

public void CanTest() 
{ 
    // Arrange 
    var foo = new Foo(); 

    using (var ts = new TransactionScope()) 
    { 
    // Act 
    var success = foo.Bar(); 

    // Assert 
    if (success) 
    { 
     Assert.That(SomethingThatTestsThatTheDataWasImported); 
    } 
    else 
    { 
     Assert.That(SomethingThatTestsThatTheRecordWasMarkedAsDuplicate); 
    } 

    // Now that we have been able to perform our Asserts, rollback. 

    } 
} 

ComplicatedDataImportCode()のコードは、このソリューションのために変更され、そしてどのような私は本当に、その結​​果であることはできません失敗シナリオで正しくロールバックすることを確認する必要があります。

また、私はこの質問の冒頭で参照した記事によると、これを行うためにTransactionScopesを使用できないことを理解しています。ここではTransactionScopesを使用して、何をしたいのかを示し、この機能を実装するための最良の代替方法を探しています。

答えて

2

これは、使用しているDBMSでサポートする必要がありますか?

SQL Serverでは実際にネストされたトランザクションはサポートされていませんが、SQL Serverではsavepointsを使用できます。

An article私は数年前に私のブログに書いた。

+1

SQL Serverはネストされたトランザクションをサポートしています。最初の 'ROLLBACK'はすべてのレベルを強制終了します。 'COMMIT'は入れ子になっています。 – Kratz

+0

ええと、SQL Serverがこれをサポートしていると誤解されているかもしれません。私はもっ​​と学びたいです。あなたのリンクを読む。今のところ+1 ... – Jaxidian

+0

@Kratz:あなたのコメントはまさに私の問題です。私は 'ROLLBACK'が全部ではなくその特定の"内部トランザクション "をロールバックするだけにします。 – Jaxidian

1

ComplicatedDataImportCodeが使用しているアクティブなDB接続を保持できる場合は、その接続でBEGIN TRANROLLBACK TRANを実行する必要があります。

+0

これで部分的なロールバックはできません。ロールバックはトランザクション全体を破棄し、それが問題です。つまり、私があなたの言うことをすれば、私はそのロールバックを実行するときに、私のCanTestメソッドによって呼び出されたときに同じトランザクション内にあるので、 'FlagSameRecordInDatabaseAsDuplicate'への呼び出しは機能しません。 – Jaxidian

関連する問題