2010-11-19 4 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(); 
} 
); 

그리고 나는 내가 여기에 자전거 환승을 개혁하고 있다고 생각 :

첫 번째 아이디어는이에 대한 somethig에 비슷한 만드는 것입니다. 트랜잭션 메커니즘을 캡슐화하지 않은 좋은 코드의 예를 제공하십시오.

Sory for my English.

+0

이것은 실제로 이전에이 문제를 해결 한 방법과 매우 유사합니다. –

+0

왜 트랜잭션을 롤백 할 때 DataException을 기록하지 않습니까? – msarchet

+1

참고로, .NET 3.0에는 이미 'Func '델리게이트가 있는데, 이는 'ResultativeAction '델리게이트와 동일한 정의입니다. –

답변

1

개인적으로 나는 AOP 지원을 사용하여 NHibernate with Spring.NET을 지원합니다. 그래서 기본적으로 SQL 트랜잭션 하에서 실행되고 싶은 메서드 인 외부 구성 파일을 정의하고 있습니다. 그것들은 일반적으로 단일 트랜잭션에서 실행하고자하는 다중 데이터 액세스 메소드를 호출 할 수있는 내 서비스 메소드입니다.

나는 트랜잭션 관리가 크로스 커팅 (crosscutting) 관심사이며 데이터 액세스 코드를 오염시킬 때 데이터 액세스 코드와 섞어서는 안된다고 생각합니다. 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 
     { 
      using (var tx = connection.BeginTransaction()) 
      { 
       DoWork1(); 
       DoWork2(); 
       DoWork3(); 
       tx.Commit(); 
      } 
     } 
     catch (DataException ex) 
     { 
      // log ex 
     } 
관련 문제