2010-11-19 19 views
0

コードでトランザクションをどのように使用していますか?C#でトランザクションを処理する一般的な方法

古い良い方法は、そのようなことやってました。

try 
{ 
    IDbTransaction tx = Connection.BeginTransaction(); 
    perform_work1 
    perform_work2 
    perform_work3 
    tx.Commit(); 

} 
catch(DbException) 
{ 
    tx.Rollback(); 
    throw; 
} 

をしかし、その後、あなたはあなたのソフトウェアにDbExceptinロギングを追加したいことを実現し、かつ、取引関連のコードのいずれかの外観を置き換える必要があります。

public static class SafeCallerProxy 
    { 
     public delegate T ResultativeAction<T>(); 

     public static T ExecuteWithResult<T>(IDbConnection conn, ResultativeAction<T> action) 
     { 
      using(IDbTransaction tx = conn.BeginTransaction()) 
      { 
       try 
       { 
        T result = action(); 
        tx.Commit(); 
        return result; 
       } 
       catch (System.Data.DataException) 
       { 
        tx.Rollback(); 
        throw; 
       } 
      } 
     } 

     public static void ExecuteAction(IDbConnection conn, Action action) 
     { 
      using (IDbTransaction tx = conn.BeginTransaction()) 
      { 
       try 
       { 
        action(); 
        tx.Commit(); 
       } 
       catch (System.Data.DataException) 
       { 
        tx.Rollback(); 
        throw; 
       } 
      } 
     } 
    } 

使い方

SafeCallerProxy.ExecuteAction(connection,() => 
{ 
    DoWork1(); 
    DoWork2(); 
    DoWork3(); 
} 
); 

そして私は、私はここにbycicleを再発明だと思う:

最初のアイデアは、これにsomethigが同様にすることです。 トランザクションメカニズムをカプセル化していない良いコードの例を挙げてください。

ソリー私の英語です。

+0

これは実際に私が過去にこの問題をどのように解決したかと非常によく似ています。 –

+0

トランザクションをロールバックするときにDataExceptionを記録するのはなぜですか? – msarchet

+1

ちょうど、ちょうど、あなたの 'ResultativeAction 'デリゲートと同じ定義を持つ.NET 3.0の 'Func 'デリゲートが既にあります。 –

答えて

1

私はAOPをサポートしていますので、私は基本的にSQLトランザクションで実行したいメソッドである外部構成ファイルを定義しています。それらは、通常は私のサービスメソッドであり、これは1つのトランザクションで実行したい複数のデータアクセスメソッドを呼び出す可能性があります。

私は、トランザクション管理がクロスカットの問題であると考え、データアクセスコードと混同しないでください。 Spring.NETはランタイム・プロキシの生成を担当し、適切なトランザクション処理コードを注入します。

+0

ありがとう、私は本当に単純なパターンを考慮する必要があります:あなたはメソッドにデコレータのpetternに類似したものを追加したいときは、本当にAOPをシミュレートしたいと思う絶好のチャンスがあります。 – v00d00

1

私はトランザクションを処理するLINQ to Entitiesを使用します。 T4テンプレートを使用して自動ログを追加するのはかなり簡単だろうと思います。

0

私が間違っていない限り、IDbTransactionインターフェイスを実装しているトランザクションオブジェクトは、Commitメソッドを呼び出す前に処理されていればロールバックを実行すると考えることができます。確かにそれは保証ではありませんが、そうしないと実装がうまくいかないと思います。

 using (var tx = connection.BeginTransaction()) 
     { 
      DoWork1(); 
      DoWork2(); 
      DoWork3(); 
      tx.Commit(); 
     } 

私は、データベースの例外をキャッチし、ログインするために必要であれば、その後、私はのtry/catchブロックを使用して全体をラップします::

私は単純に次のようにあなたの例を記述し、ということを考えると

 try 
     { 
      using (var tx = connection.BeginTransaction()) 
      { 
       DoWork1(); 
       DoWork2(); 
       DoWork3(); 
       tx.Commit(); 
      } 
     } 
     catch (DataException ex) 
     { 
      // log ex 
     } 
関連する問題