분산 트랜잭션
적용 대상: .NET Framework .NET .NET Standard
트랜잭션은 하나의 단위로 성공(커밋)하거나 실패(중단)한 관련 작업의 집합입니다. ‘분산 트랜잭션’은 여러 리소스에 영향을 주는 트랜잭션입니다. 분산 트랜잭션을 커밋하는 경우 모든 참가자는 데이터의 모든 변경 내용이 영구적으로 유지된다는 것을 보증해야 합니다. 시스템 작동이 중단되거나 다른 예측할 수 없는 이벤트가 발생해도 변경 내용이 지속되어야 합니다. 참가자 중 하나라도 이러한 보증을 이행하지 못하면 전체 트랜잭션이 실패하게 되며 트랜잭션 범위 내의 모든 데이터 변경 내용이 롤백됩니다.
참고
Azure SQL Database 및 Azure SQL Managed Instance의 분산 트랜잭션에 대한 자세한 내용은 클라우드 데이터베이스의 분산 트랜잭션을 참조하세요.
System.Transactions 사용
.NET에서 분산 트랜잭션은 System.Transactions 네임스페이스의 API를 통해 관리됩니다. 여러 영구 리소스 관리자가 관련되어 있는 경우 System.Transactions API는 MS DTC(Microsoft Distributed Transaction Coordinator)와 같은 트랜잭션 모니터에 분산 트랜잭션 처리를 위임하게 됩니다. 자세한 내용은 트랜잭션 기본 사항을 참조하세요.
ADO.NET 2.0에서는 연결을 EnlistTransaction
인스턴스에 기록하는 Transaction 메서드를 사용하여 분산 트랜잭션에 기록하는 새로운 기능을 지원합니다. 이전 버전의 ADO.NET에서는 연결의 EnlistDistributedTransaction
메서드를 사용하여 연결을 이전 버전과의 호환성이 지원되는 ITransaction 인스턴스에 인리스트먼트함으로써 분산 트랜잭션에 명시적으로 인리스트먼트했습니다. Enterprise Services 트랜잭션에 관한 자세한 내용은 Enterprise Services 및 COM+ 트랜잭션과 상호 운용성을 참조하세요.
SQL Server 데이터베이스에서 Microsoft SqlClient Data Provider for SQL Server와 함께 System.Transactions 트랜잭션을 사용하는 경우 간단한 Transaction이 자동으로 사용됩니다. 그러면 필요할 때만 트랜잭션을 완전 분산 트랜잭션으로 승격시킬 수 있습니다. 자세한 내용은 SQL Server와의 System.Transactions 통합을 참조하세요.
분산 트랜잭션에 자동 등록
자동 인리스트먼트는 ADO.NET 연결과 System.Transactions
를 통합하는 기본 방식입니다. 연결 개체는 트랜잭션이 활성화되어 있음을 인지하는 경우 기존 분산 트랜잭션에 자동으로 인리스트먼트합니다. System.Transaction
의 측면에서 볼 때 트랜잭션이 활성화되어 있다는 것은 Transaction.Current
가 null이 아님을 의미합니다. 자동 트랜잭션 인리스트먼트는 연결이 열려 있을 때 발생하며 그 이후에는 트랜잭션 범위 내에서 명령이 실행되더라도 발생하지 않습니다. Enlist=false
를 SqlConnection.ConnectionString의 연결 문자열 매개 변수로 지정하여 기존 트랜잭션에서 자동 등록을 사용하지 않도록 설정할 수 있습니다.
분산 트랜잭션에 수동 등록
자동 등록이 사용되지 않거나 연결이 열린 후 시작된 트랜잭션을 등록해야 하는 경우 Microsoft SqlClient Data Provider for SQL Server에서 SqlConnection 개체의 EnlistTransaction
메서드를 사용하여 기존 분산 트랜잭션에 등록할 수 있습니다. 기존 분산 트랜잭션에 인리스트먼트하면 트랜잭션이 커밋되거나 롤백되는 경우 데이터 소스 코드에서 변경된 내용도 함께 커밋되거나 롤백됩니다.
참고
트랜잭션이 활성화된 상태에서 DataReader
를 시작하는 경우 트랜잭션을 커밋하거나 롤백하면 예외가 throw됩니다.
분산 트랜잭션 인리스트먼트는 특히 비즈니스 개체를 풀링할 때 적용할 수 있습니다. 비즈니스 개체가 열린 연결로 풀링되는 경우 해당 연결이 열리면 자동 트랜잭션 인리스트먼트만 발생합니다. 풀링된 비즈니스 개체를 사용하여 여러 트랜잭션을 수행하는 경우 해당 개체에 대해 열린 연결은 새로 초기화된 트랜잭션에 자동으로 인리스트먼트하지 않습니다. 이 경우 연결에 대해 자동 트랜잭션 인리스트먼트를 비활성화한 다음 EnlistTransaction
을 사용하여 연결을 트랜잭션에 인리스트먼트할 수 있습니다.
EnlistTransaction
은 기존 트랜잭션에 대한 참조인 Transaction 형식의 단일 인수를 사용합니다. 연결의 EnlistTransaction
메서드를 호출한 후에는 해당 연결을 통해 데이터 소스에서 수정된 모든 내용이 트랜잭션에 포함됩니다. null 값을 전달하면 현재 분산 트랜잭션 인리스트먼트에서 연결의 인리스트먼트가 취소됩니다. 연결은 EnlistTransaction
을 호출하기 전에 열려야 합니다.
참고
트랜잭션에 연결을 명시적으로 인리스트먼트하면 첫 번째 트랜잭션이 종료될 때까지 인리스트먼트를 취소하거나 다른 트랜잭션에 인리스트먼트할 수 없습니다.
주의
연결의 EnlistTransaction
메서드를 사용하여 연결에서 트랜잭션이 이미 시작된 경우에는 BeginTransaction이 예외를 throw합니다. 그러나 트랜잭션이 데이터 소스에서 시작된 로컬 트랜잭션(예: SqlCommand를 사용하여 명시적으로 BEGIN TRANSACTION 문 실행)인 경우에는 EnlistTransaction
이 로컬 트랜잭션을 롤백하고 요청 시 기존 분산 트랜잭션에 인리스트먼트합니다. 로컬 트랜잭션이 롤백되었다는 알림은 전송되지 않으므로 BeginTransaction을 사용하여 시작되지 않은 로컬 트랜잭션을 관리해야 합니다. SQL Server에서 Microsoft SqlClient Data Provider for SQL Server를 사용하는 경우 등록을 시도하면 예외가 throw됩니다. 다른 모든 경우는 탐지되지 않습니다.
SQL Server의 승격 가능한 트랜잭션
SQL Server에서는 필요한 경우에만 간단한 로컬 트랜잭션을 분산 트랜잭션으로 자동 승격시킬 수 있는 승격 가능한 트랜잭션을 지원합니다. 승격 가능한 트랜잭션은 추가 오버헤드가 필요한 경우를 제외하고 분산 트랜잭션의 추가 오버헤드를 호출하지 않습니다. 자세한 내용과 코드 샘플은 SQL Server와의 System.Transactions 통합을 참조하세요.
분산 트랜잭션 구성
분산 트랜잭션을 사용하기 위해 네트워크에서 MS DTC를 사용해야 할 수도 있습니다. 서버의 로컬 Windows 방화벽이 활성화되어 있는 경우 MS DTC 서비스에서 네트워크를 사용하거나 MS DTC 포트를 열 수 있도록 허용해야 합니다.