2012-04-07 4 views
2

현재 트랜잭션 스코프 타임 아웃에 대해 알고 있습니다.트랜잭션 스코프 타임 아웃 이해하기

트랜잭션이 설정된 시간 초과 시간보다 오래 실행 된 경우 transaction.complete()가 호출 될 때 예외가 발생합니다. 따라서 트랜잭션 내의 처리가 X 분 동안 으로 진행 중이면 X 분 후에 transaction.complete를 호출해야합니다.

우리는 웹 서비스 내에서 transactionscope를 사용하고 있습니다. 웹 요청의 최종 사용자 은 트랜잭션이 중단되고 예외가 버블 링되기 전에 X 분 동안 기다려야합니다.

그러나 HttpWebRequest의 기본 시간 제한은 msdn에 따라 100 초입니다. 클라이언트 시간이 인데 100 초가 지나면 트랜잭션 스코프에 시간 제한이 생깁니다. 이렇게하면 데이터베이스의 일관성을 유지할 수 있습니다.

타임 아웃에 대한 나의 이해가 정확합니까?

질문 : 최종 사용자가 거래 결과를 확인하는 데 걸리는 시간을 최소화하고 싶습니다. 대기 시간을 최소화하기 위해 중첩 된 트랜잭션 스코프를 사용하여 코드를 분할하기로 결정했습니다. 각 트랜잭션 스코프는 타임 아웃이 15 초입니다. 하위 트랜잭션이 15 초보다 오래 걸리는 경우 우리는 전체 트랜잭션을 중단합니다.

여기에 자식 트랜잭션의 시간 초과가 무시 된 것으로 보입니다. 부모 트랜잭션의 시간 초과가 호출 된 후에 만 ​​예외가 발생합니다. 다음 코드에서 ChildTransaction()은 항상 true를 반환합니다. 대기 시간을 최소화하는 권장 방법은 무엇입니까? 당신이 trans.Complete를 호출 할 때 트랜잭션의 길이 만 결정

(: 코드는 1 분 기본 시간 제한이 너무 코드가 그것을 이런 식으로 보는 청소기

internal bool RootTransaction() 
    {   
     using (TransactionScope transaction = new TransactionScope()) 
     { 
      try 
      { 
       bool result = ChildTransaction(); 

       //The result is always true. 
       if (!result) 
        return result;          

       for (int counter = 0;counter <= 10;counter++) 
       {      
        //Either sleep OR do some processing 
        System.Threading.Thread.Sleep(5000); 
        // 
        //Dosomeprocess() 
       }      
       transaction.Complete();      
       return true; 
      } 
      catch (Exception e) 
      {      
       return false; 
      } 
     }       
    } 

    internal bool ChildTransaction() 
    {    
     using (TransactionScope transaction = new TransactionScope()) 
     { 
      try 
      { 
    //Sleep for 70 seconds 
       System.Threading.Thread.Sleep(70000); 
       transaction.Complete();      
      }     
      catch (Exception e) 
      { 
       return false; 
      }     
     } 
     return true; 
    } 
+0

예외를 true/false 반환 코드로 바꾸는 것이 거의 불가능합니다. 웹 서비스 호출의 일부로 트랜잭션 *을 사용하고 있습니까? 이러한 분산 트랜잭션은 실제로 치명적일 수 있습니다. 아니면 트랜잭션이 웹 서비스 구현에 로컬인가? –

+0

번호 트랜잭션이 웹 서비스 호출의 일부가 아닙니다. 웹 서비스 언급은 컨텍스트를 설정하는 것이 었습니다. 서비스는 원 자성이며 ​​일부는 트랜잭션이 필요한 데이터 삽입을 처리합니다. 또한 true false는 테스트 목적으로 만 사용됩니다. 우리는 예외에 대한 로깅 프레임 워크 등을 별도로 가지고 있습니다. – user529265

+0

K. 기록을 위해, 나는 자식 거래의 많은 부분이 존중받을 것이라고 나는 확신하지 못한다. 가장 바깥 쪽 트랜잭션 규칙은 TS입니다. 타임 아웃은 두 배가되지 않아야합니다. 시간 초과가 X 초인 경우 호출에서 x 초가 아니고 x 초가 아닌 처음으로 아무 때나 x 초가됩니다. 귀하의 예에서는 거래 된 자원이 관련되어 보이지 않으므로 특정 행동에 관해 이야기하기가 어렵 기 때문에 조금 까다 롭습니다. 하지만 트랜잭션 자체는 시간 초과가 아닙니다. –

답변

1

한번에 보여줍니다) 또는 트랜잭션 범위를 종료하십시오. 다음 코드를 가지고 : 그것은 한 경우는 이해가되지 것 수면 루틴 내부 동안 시간 제한 예외를 throw 할 수있는 방법이 없습니다

using (var trans= new TransactionScope()) 
{ 
Threading.Sleep(99999); 
trans.Complete() 
} 

. 따라서 트랜잭션 시간 제한을 사용하면 트랜잭션이 시간 초과보다 오래 걸리면 커밋되지 않을 것입니다.

하나의 쿼리 만 실행하면 (트랜잭션을 사용하는 것이 무엇인지 알 수 없음) 쿼리/명령 시간 초과 (또는 호출 한 시간)를 설정할 수 있습니다. IIRC에서는 제한 시간이 만료 된 후 쿼리가 즉시 반환됩니다.

또 다른 방법은 웹 서비스 요청 시간 제한을 설정하는 것일 뿐이고, 웹 서비스가 거래 내역이 너무 길어서 응답하는 데 너무 오래 걸리는 것으로 가정합니다.

편집 : 당신은 시도 할 수 있습니다 : 다른 스레드에 거래를 산란

  • 하고 주 스레드합니다 (웹 서비스에 의해 사용 하나 (Thread.join를 (시간 제한)를 사용하여) 완료 될 때까지 기다립니다 요구). 따라서 지정한 시간 초과 전에 종료하지 않으면 대기를 멈추고 시간 초과 오류를 반환 할 수 있습니다. 트랜잭션을 중단하기 위해 다른 스레드에 신호를 보내는 것을 잊지 마십시오.
  • 이러한 트랜잭션 내에서만 SQL 쿼리를 수행한다고 가정하면 "BEGIN TRANSACTION"키워드를 사용하여 sql 스크립트 (실제로 hacky)에서 트랜잭션을 지정할 수 있습니다. 그런 다음 명령 제한 시간을 지정하고이 모든 것을 한 줄의 코드로 실행할 수 있습니다. 그러나 그 다음에는 트랜잭션 내부에서 수행하는 모든 작업을 SQL 스크립트로 옮겨야합니다.이 스크립트는 사용자에게 가능하거나 불가능할 수 있으며 깨끗하지 않습니다.