2009-11-26 2 views
0

관련 질문을 통해 좋은 호랑이를 찾아 내고 구현 된 제안을 찾았지만 .NET TransactionScope에는 여전히 문제가 있습니다.TransactionScope는 두 번째 서비스 오류가 있음에도 불구하고 부분 업데이트가 가능합니다.

메서드에서 두 개의 WCF 서비스를 호출하고 있는데 두 번째 서비스 오류 (의도적으로이 경우)가 첫 번째 서비스가 롤백되지 않더라도. 문제를 설명하기 위해 간단한 테스트 응용 프로그램을 만들었습니다. (연결 익명 제조)

private void TryATransaction() 
{ 
    ServiceReference1.IService1 service = new ServiceReference1.Service1Client(); 
    ServiceReference2.IService1 service2 = new ServiceReference2.Service1Client(); 

    using (TransactionScope scope = new TransactionScope()) 
    { 
     service.TestMethod("one"); 
     service2.UpdateSomethingElse("two"); 

     scope.Complete(); 
    } 
} 

제 서비스가 다음과 같다 :

public bool TestMethod(string anything) 
{ 
     using (TransactionScope scope = new TransactionScope()) 
     { 

      // connect to a db 
      using (SqlConnection connection = new SqlConnection("Data Source=DATASOURCE;Initial Catalog=DATABASE;Integrated Security=SSPI;Transaction Binding=Explicit Unbind;")) 
      { 

       connection.Open(); 
       // save something 
       SqlCommand command1 = new SqlCommand("EXECUTE [DATABASE].[dbo].[uspUpdateCustomer] 3, '[email protected]', 1, null", connection); 
       command1.ExecuteNonQuery(); 
       connection.Close(); 

      } 

      scope.Complete(); 
     } 

    return true; 
} 

그리고 상기 제 2 서비스는 점을 제외하고 첫 번째 서비스 동일 여기서

는 호출 방법 데이터베이스의 다른 필드를 갱신합니다.

1) 오류없이 강제 실행하면 모든 필드가 올바르게 업데이트됩니다.

2)이 서비스를 실행하고 두 번째 서비스에서 오류가 발생하면 첫 번째 서비스의 업데이트가 데이터베이스에 커밋되지만 두 번째 서비스는 롤백됩니다 (오류는 ExecuteNonQuery 문 이후입니다).

이 예제 코드는 기본적으로 여기에있는 예제를 다음과 http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

그리고 기타 관련 질문에 추천되었다 명시 바인드 해제를 덧붙였다.

귀하의 제안은 대단히 환영합니다. 필요한 경우 추가 정보를 제공해 드리겠습니다.

추가 정보

분산 식별자는 항상 00000000-0000-0000-0000-000000000000 것 같다 -이 단서의 경우 모르겠어요. f6446876-496d-488c-a21c-1e4c4295d50c - 여기

(즉 위하여) 배포 ID 및 로컬 ID의 dubug 출력

현재 트랜잭션 00000000-0000-0000-0000-000000000000이다 2

현재 트랜잭션이다음과 같습니다 : - 7edd5ba3-7f5a-42af-b9ca-37b3862c26a7 8

현재 트랜잭션이 00000000-0000-0000-0000-000000000000입니다 0 00000000-0000-0000-0000-000000000000 - 6fa0e3f7-b655-40ad-8bdd-f0670de79a49는 2

트랜잭션 내 예를 들어, 응용 프로그램에서 aspx 페이지 뒤에 코드를 통해 시작되고있다.

+0

한 가지 질문 : 코드를 보면 TransactionScope가 클라이언트와 서버 경계에서 작동 할 것으로 기대하고 있습니다. 그것을 지원합니까? –

답변

1

편집 : 미안하지만 거꾸로합니다.

대부분의 경우 문제는 WCF와 함께 트랜잭션을 사용하기 때문일 수 있습니다.

트랜잭션 서비스에 관한 this 문서를 확인하십시오.특히 클라이언트/서비스 모드 트랜잭션 부분.

  • 이 서비스
  • 제거의 BindingContext를에 TransactionFlowBindingElement를 추가하여 OperationContract를 인터페이스 방법
  • [TransactionFlow(TransactionFlowOption.Mandatory)] 속성을 설정 구현에 [OperationBehavior(TransactionScopeRequired = true)] 속성을 설정합니다

    은 기본적으로 다음을 수행해야합니다 고객의 TransactionScope를 사용하고 있기 때문에 서비스 구현에서 TransactionScope을 가져와야합니다.

(기본 TransactionAutoComplete = true OperationBehavior를 사용하는 경우) 트랜잭션 완료에 성공한 각 서비스 메소드가 성공합니다.

예외로 인해 서비스 메소드가 실패하면 트랜잭션에 실패한 것으로 간주합니다.

+0

내 문제는 그 반대입니다. 두 서비스를 호출하는 메소드에서 작성한 앰비언트 트랜잭션을 사용하려면 내부 트랜잭션을 사용하고 싶습니다. 따라서 서비스가 실패하면 전체 로트가 롤백됩니다. – Fenton

+0

예 - 그 속성이 핵심입니다. 조정 해 주셔서 감사합니다. – Fenton

+0

기꺼이 도와 드리겠습니다. :-) –

관련 문제