2010-08-21 7 views
6

나는 System.Transactions 네임 스페이스를 보았고, 실제로이 네임 스페이스 사용법을 사용하여 RDMBS를 만들 수 있습니까?System.Transactions의 실용적인 용도는 무엇입니까?

하지만 몇 가지 예를 보았을 때 System.Transactions가 간단한 시도를 넘어서 성공/실패 결과를 얻는 것 이외의 다른 방법을 이해하지 못합니다.

이것은 MSDN의 웹 사이트에있는 예제입니다. 매우 간단 할 수 있지만이 샘플의 이점을 이해할 수 없다는 것을 알고 있습니다. 다음 예제에서 간단한 try/catch와 Transaction scope의 차이점을 말해 줄 수 있습니까? .

RDBMS (내 자신의 RDMBS 만들기)를 작성해야한다면, 우리는 우리가 실행하는 작업의 디스크에 많은 로그를 작성해야한다는 것을 알고 있으며, 결국에는 롤백의 경우 해당 작업을 실행 취소하지만 여기에는 아무것도 되돌리기위한 것이 없습니다.

// This function takes arguments for 2 connection strings and commands to create a transaction 
// involving two SQL Servers. It returns a value > 0 if the transaction is committed, 0 if the 
// transaction is rolled back. To test this code, you can connect to two different databases 
// on the same server by altering the connection string, or to another 3rd party RDBMS by 
// altering the code in the connection2 code block. 
static public int CreateTransactionScope(
    string connectString1, string connectString2, 
    string commandText1, string commandText2) 
{ 
    // Initialize the return value to zero and create a StringWriter to display results. 
    int returnValue = 0; 
    System.IO.StringWriter writer = new System.IO.StringWriter(); 

    try 
    { 
     // Create the TransactionScope to execute the commands, guaranteeing 
     // that both commands can commit or roll back as a single unit of work. 
     using (TransactionScope scope = new TransactionScope()) 
     { 
      using (SqlConnection connection1 = new SqlConnection(connectString1)) 
      { 
       // Opening the connection automatically enlists it in the 
       // TransactionScope as a lightweight transaction. 
       connection1.Open(); 

       // Create the SqlCommand object and execute the first command. 
       SqlCommand command1 = new SqlCommand(commandText1, connection1); 
       returnValue = command1.ExecuteNonQuery(); 
       writer.WriteLine("Rows to be affected by command1: {0}", returnValue); 

       // If you get here, this means that command1 succeeded. By nesting 
       // the using block for connection2 inside that of connection1, you 
       // conserve server and network resources as connection2 is opened 
       // only when there is a chance that the transaction can commit. 
       using (SqlConnection connection2 = new SqlConnection(connectString2)) 
       { 
        // The transaction is escalated to a full distributed 
        // transaction when connection2 is opened. 
        connection2.Open(); 

        // Execute the second command in the second database. 
        returnValue = 0; 
        SqlCommand command2 = new SqlCommand(commandText2, connection2); 
        returnValue = command2.ExecuteNonQuery(); 
        writer.WriteLine("Rows to be affected by command2: {0}", returnValue); 
       } 
      } 

      // The Complete method commits the transaction. If an exception has been thrown, 
      // Complete is not called and the transaction is rolled back. 
      scope.Complete(); 

     } 

    } 
    catch (TransactionAbortedException ex) 
    { 
     writer.WriteLine("TransactionAbortedException Message: {0}", ex.Message); 
    } 
    catch (ApplicationException ex) 
    { 
     writer.WriteLine("ApplicationException Message: {0}", ex.Message); 
    } 

    // Display messages. 
    Console.WriteLine(writer.ToString()); 

    return returnValue; 
} 

위의 예에서 우리는 무엇을하고 있습니까? 나는 SQL Client 라이브러리가 모든 것을 올바르게 수행 할 것이라고 추측합니다. 이것은 System.IO.StringWriter가 모든 성공 텍스트 또는 모든 실패 텍스트를 포함한다는 것을 의미합니까? 또는 TransactionScope의 범위 사이에 잠금이 있습니까?

+0

"make a RDBMS"란 무엇을 의미합니까? – nos

+0

관계형 데이터베이스 관리 시스템, SQL Server 또는 MySQL 또는 Oracle의 사본, 내 자신의 XYZSql 데이터베이스 시스템을 .net으로 만들고 싶다면 이것을 사용할 수 있습니까? –

+1

새로운 XYZSql 데이터베이스 시스템이 트랜잭션을 지원하는 경우 실제로는 아니지만 .NET XYZSql ADO.NET 드라이버에서 System.Transactions에 대한 지원을 구현할 수 있습니다. – nos

답변

3

먼저 TransactionScope은 try/catch와 다릅니다. TransactionScope는 트랜잭션의 이름 범위입니다. 범위의 트랜잭션은 범위에서 완료를 호출하여 명시 적으로 커밋해야합니다. 다른 모든 경우 (범위에서 발생한 예외 포함)는 범위를 처리하고 불완전한 트랜잭션을 암시 적으로 롤백하는 블록을 사용하여 마무리되지만 결과는 예외를 처리하지 않습니다.

기본 시나리오에서 System.Transactions의 트랜잭션은 db 클라이언트 트랜잭션과 동일하게 작동합니다. System.Transactions는 다음과 같은 추가 기능을 제공합니다.

  • API 불가 지론. 오라클, SQL 서버 또는 웹 서비스에 대해 동일한 트랜잭션 범위를 사용할 수 있습니다. 이것은 트랜잭션이 persistance 무식한 (지속성 구현에 대한 정보를 모르는) 계층에서 시작될 때 중요합니다.
  • 자동 참여. 연결 문자열에 지정된 경우 (기본 동작). 새로운 데이터베이스 연결은 자동으로 기존 트랜잭션으로 연결됩니다.
  • 분산 트랜잭션에 자동 승격.두 번째 연결이 트랜잭션에 추가되면 distirbuted 트랜잭션으로 자동 승격됩니다 (MSDTC가 필요함). 프로모션은 트랜잭션 웹 서비스와 같은 다른 조정 된 리소스를 등록 할 때도 작동합니다.
1

거래가 필요한 잠금을 수행합니다. 또한 주석이 제안한대로 Complete()에 의해 커밋되지 않은 경우 트랜잭션이 범위 끝에서 처리 될 때 암시 적 롤백이 발생합니다. 따라서 예외가 발생하면 모든 작업이 자동으로 롤백되고 데이터베이스에서 변경 작업이 수행되지 않습니다. 예를 들어 두 번째 쿼리가 실패하면 첫 번째 쿼리의 변경 내용이 삭제됩니다.

그러나 StringWriter를 위해, 그것은 여전히 ​​실패 지점에 메시지를 포함합니다 (예를 들어

Rows to be affected by command1: {0} 
ApplicationException Message: {0} 

은 모두이 코드 후 로그에 나타날 수있다. 가진 RDBMS를 만드는으로

이 클래스는 정말로 당신의 질문을 이해하지 못합니다. 실제로 관계형 데이터베이스 관리 시스템을 만들고 싶다면 아마도 잘못된 장소를보고 있다고 말할 수 있습니다. 트랜잭션을 통해 RDBMS에 액세스하려면, 나는 당신의 요구에 달려 있다고 말하고 싶습니다. 예를 들어, 귀하의 진술이 주문 및 모든 - 또는 - 없음 패션, 다음 예, 거래 시작하는 것이 좋습니다.

+0

예, RDBMS를 만들려고합니다. SqlTransaction과 같은 데이터베이스 클라이언트 라이브러리 트랜잭션을 사용할 수 있다는 것을 알고 있습니다. 그러나 필요한 잠금으로 무엇을 의미하는지 이해하지 못합니다. 여기서 TransactionScope을 사용하지 마십시오. 어떤 명령이든 실패 할 경우 동일한 결과를 얻을 수 있습니까? –

+0

다시 죄송합니다.이 코드에서 SqlTransaction을 명시 적으로 사용하지 않았더라도 System.Transactions가 Sql 데이터베이스의 변경 사항을 암시 적으로 취소한다는 의미입니까? 이것은 Sql 클라이언트 라이브러리가 자동으로 SqlTransaction의 인스턴스를 생성하고 사용하므로 실질적으로 SqlTransaction을 사용할 수있을 때 System.Transactions를 사용하지 않는다는 의미입니다. –

+0

TransactionScope는 SqlTransaction보다 많은 인수이며, SqlTransaction, e, g, MSMQ 트랜잭션 이외의 다른 것들을 확장 할 수 있습니다. – nos

관련 문제