2009-05-26 3 views
7

私のWebアプリケーションでは、ユーザーの操作を監査しています。したがって、ユーザーがアクションをとるたびに、アクションが実行されたオブジェクトを更新し、そのアクションの監査証跡を保持します。サブソニックとトランザクションを使用する

ここでオブジェクトを最初に変更してから監査証跡を更新しても監査証跡が失われたらどうしますか?

明らかに、変更されたオブジェクトへの変更をロールバックする必要があります。私は単純なアプリケーションでSql-Transactionsを使うことができますが、私はSubsonicを使ってdbと話しています。どのように私は状況に対処することができますか?以下のような

答えて

10

何か:

Using ts As New System.Transactions.TransactionScope() 
    Using sharedConnectionScope As New SubSonic.SharedDbConnectionScope() 

' Do your individual saves here 

' If all OK 
     ts.Complete() 

    End Using 
End Using 
+1

私は、TransactionScopeがSubSonicで正しく動作することを確認でき、トランザクションを正しくロールバックします。 – kd7

+0

ありがとう@kevinwと@bnkdev。私はC#を使用していますので、他の人がすぐに使用できるようにC#でコードを投稿します。また、個々のセーブやアクションをtry/catchの中に入れないで、Okかどうかを知ることは簡単ですか? – TheVillageIdiot

14

@Kevinwによって与えられたanswerは完全に大丈夫です。私はちょうどC#コードへの彼の答えの翻訳としてこれを投稿しています。私はコードを書式化しないので、コメントを使用していない:)また、トランザクションが完了するかロールバックするかどうかを知るためにtry/catchを使用しています。

using (System.Transactions.TransactionScope ts = new TransactionScope()) 
{ 
    using (SharedDbConnectionScope scs = new SharedDbConnectionScope()) 
    { 
     try 
     { 
      //do your stuff like saving multiple objects etc. here 

      //everything should be completed nicely before you reach this 
      //line if not throw exception and don't reach to line below 
      ts.Complete(); 
     } 
     catch (Exception ex) 
     { 
      //ts.Dispose(); //Don't need this as using will take care of it. 
      //Do stuff with exception or throw it to caller 
     } 
    } 
} 
+1

catch文の中で 'ts.Dispose()'を呼び出すことは必須ではありません。なぜなら、usingステートメントはそれをどうにか処理するからです。一般的なケースでは、「SharedDbConnectionScope」またはトランザクションスコープ内で起動される他のトランザクション認識コードが、囲みトランザクションスコープが破棄される前に処理されることに依存する可能性があるため、問題を引き起こす可能性があります。 –

+0

@OskarBerggrenがコメントしました。 – TheVillageIdiot

1

いいえ。 SharedDbConnectionScopeを外に置くと、変更はデータベース内の可視であり、ts.Complete()より前です。内部に置くと、操作が完了するまでサーバーがブロックされます。

関連する問題