MSSQL 서버 MSDTC 원리 이해와 설정/사용 방법
한 번의 비즈니스 트랜잭션이 두 대 이상의 DB 서버(또는 여러 리소스) 를 동시에 갱신해야 한다면, 사실상 MSDTC(Microsoft Distributed Transaction Coordinator) 를 이해하는 것이 필수입니다.
MSDTC는 내부적으로 2-Phase Commit(2PC) 을 사용해 “모두 성공(Commit) 또는 모두 실패(Rollback)”를 강제합니다.

시나리오(간단 정리)
- AP01: Application Server (Web/WAS, .NET, Java 등)
- DB01 / DB02: SQL Server 2대(서로 다른 인스턴스/서버)
AP01에서 다음과 같이 하나의 논리 트랜잭션으로 작업이 수행된다고 가정합니다.
옵션 A) 애플리케이션(.NET)에서 두 DB 연결을 하나의 트랜잭션으로 묶기
using System.Transactions;
using Microsoft.Data.SqlClient;
using (var scope = new TransactionScope())
{
using (var c1 = new SqlConnection("Server=DB01;Database=OrderDB;Trusted_Connection=True;"))
{
c1.Open();
// INSERT/UPDATE on DB01
}
using (var c2 = new SqlConnection("Server=DB02;Database=InventoryDB;Trusted_Connection=True;"))
{
c2.Open();
// INSERT/UPDATE on DB02
}
scope.Complete();
}
이처럼 한 트랜잭션 컨텍스트에서 서로 다른 서버에 연결하면, 트랜잭션이 “분산 트랜잭션”으로 승격되며 MSDTC가 개입합니다.
옵션 B) T-SQL에서 Linked Server 기반 분산 트랜잭션(대표 예시)
DB01에서 DB02로 Linked Server가 구성되어 있다는 가정 하에:
BEGIN DISTRIBUTED TRANSACTION;
INSERT INTO OrderDB.dbo.Orders (OrderID, Amount)
VALUES (1, 10000);
INSERT INTO [DB02].[InventoryDB].dbo.Stock (ProductID, Qty)
VALUES (1, -1);
COMMIT TRANSACTION;
환경/드라이버/설정에 따라
BEGIN DISTRIBUTED TRANSACTION없이도 자동으로 분산 트랜잭션으로 승격될 수 있지만, 의도/가독성을 위해 명시하는 패턴이 흔합니다.
1. 준비 과정: 방화벽, HOSTNAME, AD/DNS, hosts 파일
1-1. MSDTC 통신 구조와 HOSTNAME
MSDTC는 서버 간 통신을 위해 기본적으로 RPC(Remote Procedure Call) 를 사용합니다.
특히 Mutual Authentication 같은 보안 모드에서는 “상대 서버의 호스트 이름/컴퓨터 계정” 기반으로 인증이 동작하는 경우가 많아, IP만으로 통신하는 구성보다 HOSTNAME(DNS 이름) 기반 통신이 안정적입니다.
권장 네이밍 예시(도메인 환경):
- AP01:
AP01.domain.local - DB01:
DB01.domain.local - DB02:
DB02.domain.local
AP01에서 기본 체크:
# Name resolution
nslookup DB01
nslookup DB02
# Basic connectivity
ping DB01
ping DB02

1-2. AD(DNS)를 사용하는 경우(권장)
기업 환경 대부분은 AD 도메인 + DNS를 사용합니다.
- 서버를 도메인에 조인하면
- 컴퓨터 계정이 AD에 생성되고
- DNS에 레코드가 자동 등록되는 구조가 일반적입니다.
이 경우 Mutual Authentication Required 같은 강한 인증 모드를 사용하기가 상대적으로 수월합니다.
정리:
- 가능하면 AP01, DB01, DB02 모두 동일 도메인(또는 신뢰 도메인)
- DNS 이름으로 상호 통신 가능 여부 확인
1-3. hosts 파일을 사용하는 경우(테스트/소규모 환경)
도메인 없이 워크그룹으로 구성된 테스트 환경이라면 hosts 파일로 이름을 강제 매핑할 수 있습니다.
- 위치:
C:\Windows\System32\drivers\etc\hosts - 예시:
10.10.10.11 DB01
10.10.10.12 DB02
10.10.10.21 AP01
이렇게 해두면 ping DB01처럼 이름 기반 통신이 가능합니다.
주의: 운영 환경에서는 DNS(AD)를 권장합니다. hosts는 변경 누락/관리 난이도로 인해 테스트 용도에 적합합니다.
1-4. 방화벽 포트 및 체크 방법
MSDTC는 RPC 기반이므로, 통상 아래 포트/범위를 고려합니다.
(정확한 범위는 OS 정책/보안 구성에 따라 달라질 수 있으나 “개념적으로” 아래 두 축이 핵심입니다.)
| 구분 | 포트 | 설명 |
|---|---|---|
| RPC Endpoint Mapper | TCP 135 | DTC 포함 RPC 서비스 엔드포인트 매핑 |
| RPC 동적 포트 | (OS 동적 범위) | 실제 DTC 세션이 사용하는 포트(현대 Windows는 보통 49152–65535 범위가 기본) |
실무 패턴은 보통 둘 중 하나입니다.
- (A) 135 + RPC 동적 포트 범위를 허용(가장 단순하지만 방화벽 정책상 어려울 수 있음)
- (B) RPC 범위를 제한하거나 MSDTC에 고정 포트를 지정하고 해당 포트만 허용(보안팀 협의 필요)
Windows 방화벽 규칙 확인 예:
Get-NetFirewallRule -DisplayName "*DTC*"
포트 체크(AP01 → DB01):
Test-NetConnection DB01 -Port 135
네트워크/보안팀과 협업 시 체크 포인트:
- AP01 ↔ DB01, AP01 ↔ DB02는 기본
- 구조에 따라 DB01 ↔ DB02도 필요할 수 있음(Linked Server 등)
- 위 경로에 대해 TCP 135 + (허용한 RPC 포트 정책) 가 쌍방향으로 열려야 함

2. MSDTC 설정 절차와 AP–DB 간 통신 구조
이 글은 AP01, DB01, DB02 모두 “Local DTC”를 설정하는 기준으로 설명합니다.
2-1. 공통: Local DTC Security 설정(3대 모두)
각 서버에서 아래 절차를 수행합니다(Windows 버전에 따라 UI 위치는 다를 수 있으나 개념은 동일).
1) 시작 → 실행 → dcomcnfg
2) Component Services → Computers → My Computer
3) Distributed Transaction Coordinator → Local DTC 우클릭 → Properties
4) Security 탭 이동
5) 환경에 맞게 옵션 설정 후 적용(적용 시 MSDTC 서비스 재시작 발생 가능)
권장(도메인 환경 기본 예시):
- Network DTC Access: On
- Allow Remote Clients: On (서로 원격 DTC 사용)
- Allow Inbound: On
- Allow Outbound: On
- Authentication:
Mutual Authentication Required(도메인 환경에서 권장) - (필요 시) Enable XA Transactions: 이기종 XA 연동 시만

2-2. 통신 구조(논리 흐름)
AP01에서 분산 트랜잭션이 시작되면 개략적으로 아래 흐름을 가집니다.
1) 애플리케이션에서 TransactionScope 또는 BEGIN DISTRIBUTED TRANSACTION 실행
2) AP01의 Local DTC가 트랜잭션 관리자(TM, Transaction Manager) 역할
3) AP01이 DB01/DB02에 연결하면서 각 DB 서버의 Local DTC와 핸드셰이크
4) DTC 간 2-Phase Commit(2PC) 수행
- Prepare 단계: DB01/DB02가 커밋 가능 여부를 확인하고 준비 상태(redo/undo 정보 기록) 응답
- Commit 단계: 둘 다 OK면 Commit, 하나라도 실패면 Rollback
이 “모두 성공 또는 모두 롤백”이 MSDTC의 핵심 원리입니다.

3. MSDTC 설정 체크 항목 상세(Security 탭 기준)
3-1. Network DTC Access
- DTC가 네트워크를 통해 다른 컴퓨터와 트랜잭션을 주고받을 수 있게 하는 기본 스위치
- 분산 트랜잭션이 필요하면 반드시 On
3-2. Client and Administration
Allow Remote Clients
- 다른 컴퓨터가 이 서버의 DTC를 “원격으로 사용”하도록 허용
- AP–DB 구조에서 보통 DB 서버에서 필수, AP 서버에서도 필요한 경우가 많음(상호 DTC 통신)
Allow Remote Administration
- 원격에서 DTC 설정 변경 허용
- 일반적으로는 필요할 때만 활성화(보안 고려)
3-3. Transaction Manager Communication
Allow Inbound
- 다른 서버에서 이 서버 DTC로 들어오는 트랜잭션을 허용
- 예) AP01 → DB01 관점에서 DB01은 Inbound
Allow Outbound
- 이 서버에서 다른 서버 DTC로 나가는 트랜잭션을 허용
- 예) DB01에서 Linked Server로 DB02에 접근(분산 트랜잭션)하는 경우 Outbound 필요
일반적인 양방향 통신 환경에서는 Inbound/Outbound 모두 On이 기본입니다.
Authentication 옵션(중요)
Mutual Authentication Required
- 양쪽 컴퓨터가 서로를 인증(도메인/Kerberos 환경에서 가장 안전한 편)
- 도메인 기반 운영 환경에서 우선 검토 대상
Incoming Caller Authentication Required
- 들어오는 쪽만 인증 요구
- 일부 클러스터/특정 네트워크 제약 환경에서 현실적인 선택이 되는 경우가 있음
No Authentication Required
- 인증 없이 통신 허용
- 워크그룹/레거시 혼재 환경에서 사용 가능하지만 보안상 위험
- 테스트/격리망 등 제한적 환경에서만 신중히 사용
Enable XA Transactions
- XA 프로토콜 기반 분산 트랜잭션 지원(Oracle, 메인프레임, 일부 JTA 등)
- 단순 SQL Server ↔ SQL Server만이라면 불필요한 경우가 많음
3-4. Logging / Tracing(간단)
Tracing
- 트랜잭션 활동/오류를 로깅
- 장애 분석 시 유용하지만, 상시 과도한 트레이싱은 성능/로그 증가에 영향
Logging
- MSDTC 트랜잭션 로그 파일 위치/크기 등
- 로그 디스크 상태/백업/모니터링까지 함께 고려(특히 장애 시)
4. MSDTC의 필요성과 실제 사용 사례
4-1. MSDTC가 필요한 이유
단일 DB 내 트랜잭션이면 SQL Server 기본 트랜잭션만으로 충분합니다.
하지만 아래처럼 트랜잭션이 “여러 리소스”에 걸치면 조정자(Coordinator)가 필요해집니다.
- 두 개 이상의 SQL Server 인스턴스(DB01, DB02)
- SQL Server + 메시지 큐(MSMQ)
- SQL Server + 파일 시스템, COM+, WCF 등
이때 트랜잭션을 한 번에 Commit/Rollback하도록 조율하는 서비스가 MSDTC입니다.
4-2. 대표적인 사용 사례
(1) 주문/결제 + 재고 시스템 분리
- OrderDB(DB01)와 InventoryDB(DB02)가 서로 다른 서버
- 한 주문 처리에서
- 주문 insert(DB01)
- 재고 감소(DB02)
- 둘 중 하나라도 실패하면 전체 롤백 필요 → MSDTC
(2) Linked Server 기반 분산 쿼리
BEGIN DISTRIBUTED TRANSACTION;
INSERT INTO OrderDB.dbo.OrderHeader (OrderID, Amount)
SELECT OrderID, Amount
FROM [DB02].[ERP].dbo.OrderSource;
COMMIT TRANSACTION;
(3) SSIS(Integration Services) 패키지
- 여러 커넥션 매니저(SQL Server, Oracle 등)를 사용하고
- 컨테이너
TransactionOption = Required등으로 분산 트랜잭션이 발생하면 MSDTC 사용
(4) COM+ / WCF / .NET Enterprise Services
- 컴포넌트/서비스 트랜잭션 속성이
RequiresNew등으로 설정되어 있고 - 다중 리소스를 다루면 MSDTC가 자동 개입

5. Local DTC vs Cluster DTC 차이와 설정 개요
5-1. Local DTC
- 각 Windows 서버에 기본으로 있는 MSDTC 인스턴스
- 트랜잭션 로그도 해당 서버 로컬 디스크에 저장
- 서버가 다운되면 해당 DTC도 같이 중단 → 고가용성(HA) 보장 X
이번 글의 기본 가정(AP01 + DB01 + DB02 단독 서버 3대)에서는 Local DTC만으로도 충분한 경우가 많습니다.
5-2. Cluster DTC(클러스터 DTC)
Windows Failover Cluster 환경에서 DTC가 필요할 수 있습니다. 특히 SQL Server FCI(Failover Cluster Instance) 와 결합되는 경우가 대표적입니다.
특징:
- Failover Cluster Manager에서 DTC를 “클러스터 역할/리소스”로 구성
- 가상 네트워크 이름, 가상 IP, 공유 디스크(트랜잭션 로그 저장) 할당
- 어느 노드로 Failover 되어도 동일한 DTC 이름/로그를 사용 → 일관성 유지
- SQL Server FCI 인스턴스와 동일한 클러스터 그룹에 배치하는 패턴이 일반적
참고: Always On 구성에서의 DTC 지원/제약은 버전/토폴로지에 따라 복잡해질 수 있으므로, 해당 환경은 별도 검토/테스트를 권장합니다.
5-3. Local vs Cluster DTC 선택 기준(요약)
| 항목 | Local DTC | Cluster DTC |
|---|---|---|
| 구성 난이도 | 낮음 | 높음(클러스터 필요) |
| 고가용성(HA) | X | O |
| 사용 시나리오 | 단독 서버, 비중요 분산 트랜잭션 | FCI, 대규모/중요 분산 트랜잭션 |
| 인증 모드 | Mutual/Incoming/None 가능 | 환경 제약으로 Mutual이 어려운 경우가 있어 Incoming/None이 현실적인 선택이 되기도 함 |

6. DTC 장애와 In-doubt 설정을 이용한 대응 방법
MSDTC 관련 장애는 종종 “트랜잭션 상태를 끝까지 확인하지 못한 경우”, 즉 In-doubt(결과를 확정 못한 상태) 에서 발생합니다.
대표 증상 예:
- DB 복구 중 “MS DTC에 연결할 수 없어 트랜잭션 상태를 확인할 수 없다…” 유사 메시지
- 잠금이 풀리지 않고 대기가 지속
- 일부 상황에서
spid = -2등 비정상/시스템 세션 형태로 관측되는 케이스
이때 핵심 옵션 중 하나가 SQL Server의 서버 구성 옵션인 in-doubt xact resolution 입니다.

6-1. in-doubt xact resolution 옵션 값
sp_configure 'in-doubt xact resolution'은 MSDTC가 결과를 알려주지 못할 때 SQL Server가 기본적으로 어떻게 처리할지 결정합니다.
| 값 | 의미 |
|---|---|
| 0 (기본값) | No presumption: 결과 불명 시 자동 결정하지 않음(관리자 개입 필요) |
| 1 | Presume Commit: 결과를 모르면 Commit으로 간주 |
| 2 | Presume Abort: 결과를 모르면 Rollback으로 간주 |
주의: 잘못 설정하면 데이터 불일치(정합성 훼손)가 발생할 수 있습니다. 운영 환경에서는 원칙적으로 기본값(0) 유지 후, 장애 상황에서만 Runbook 기반으로 일시 적용하는 방식이 안전합니다.
6-2. 설정 예제
(1) In-doubt 상황에서 일시적으로 Abort(Rollback) 선호로 처리하고 싶을 때
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'in-doubt xact resolution', 2; -- Presume Abort
RECONFIGURE;
-- 복구/서비스 정상화 후 기본값(0) 복귀 권장
EXEC sp_configure 'in-doubt xact resolution', 0;
RECONFIGURE;
EXEC sp_configure 'show advanced options', 0;
RECONFIGURE;
(2) 부득이하게 Commit 선호(1)가 필요한 상황
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'in-doubt xact resolution', 1; -- Presume Commit
RECONFIGURE;
실제로는 비즈니스 특성에 따라 “Commit 가정(1)”과 “Abort 가정(2)”의 위험도가 다르므로, 가능하면 사전에 DR 시나리오/테스트로 기준을 확정해 두는 것이 좋습니다.
6-3. 개별 In-doubt 트랜잭션 수동 처리(KILL UOW 등)
SQL Server에서 분산 트랜잭션은 보통 UOW(Unit of Work GUID) 로 식별됩니다.
분산 트랜잭션 확인(대표 패턴):
-- 분산 트랜잭션(Distributed)만 조회
SELECT *
FROM sys.dm_tran_active_transactions
WHERE transaction_type = 4; -- 4 = Distributed
세션 매핑이 필요하면(상황에 따라):
SELECT
st.session_id,
at.transaction_id,
at.name,
at.transaction_type,
at.transaction_state
FROM sys.dm_tran_session_transactions st
JOIN sys.dm_tran_active_transactions at
ON st.transaction_id = at.transaction_id
WHERE at.transaction_type = 4;
정말 필요한 경우에 한해 UOW(GUID)를 대상으로 종료하는 패턴이 있습니다(환경/상황에 따라 매우 위험할 수 있으므로, 실행 전후 정합성 검증이 필수).
-- 예시: UOW GUID로 KILL (GUID는 예시)
KILL '6BAC37B8-6515-4FC1-972B-C059D1D5133E';
권장 대응 순서(현장 Runbook 관점):
1) MSDTC/네트워크 상태 확인(서비스, 방화벽, 인증 설정)
2) in-doubt 상황인지 판단(로그/DMV)
3) in-doubt xact resolution을 일시 적용할지 결정(조심스럽게)
4) 정말 불가피할 때만 개별 KILL 수행
5) 이후 데이터 정합성(주문/재고 등 핵심 엔티티) 검증
7. 자주 묻는 질문(FAQ)
Q1. MSDTC를 반드시 켜야 하나요?
- 단일 서버·단일 DB 인스턴스에서만 트랜잭션을 사용한다면 꼭 필요하지 않을 수 있습니다.
- 다만 아래 중 하나라도 해당되면 MSDTC 활성화가 필요할 가능성이 큽니다.
- Linked Server 사용
- 여러 SQL 인스턴스를 동시에 갱신
.NET TransactionScope로 여러 커넥션을 묶는 경우
Q2. MSDTC 포트는 135만 열면 되나요?
- 일반적으로 TCP 135 + RPC 동적 포트가 필요합니다.
- 방화벽 정책상 동적 포트를 모두 열기 어렵다면
- RPC 포트 범위를 제한하거나
- MSDTC 고정 포트를 사용하도록 구성하고
- 그 포트만 허용하는 패턴이 흔합니다.
Q3. 도메인(AD) 없이도 MSDTC를 쓸 수 있나요?
- 가능은 합니다(예: hosts로 이름 매핑 +
No Authentication Required). - 다만 보안/운영 측면에서 권장되지는 않으며, 테스트/소규모 환경에서만 신중히 사용합니다.
Q4. Local DTC만 써도 되나요? Cluster DTC는 언제 필요하죠?
- 단독 서버 구조면 Local DTC만으로 충분한 경우가 많습니다.
- SQL Server FCI 같은 고가용성(HA) 환경에서 DTC 가용성이 중요하면 Cluster DTC를 고려합니다.
Q5. In-doubt 옵션을 1(Commit 가정)로 해두면 편하지 않나요?
- 장애가 “넘어간 것처럼” 보일 수 있지만, 실제로는 실패한 트랜잭션을 Commit으로 간주할 위험이 있습니다.
- 원칙적으로 기본값(0)을 유지하고, 장애 상황에서만 일시 적용하는 Runbook이 더 안전합니다.
체크리스트(AP01 1대 + DB01/DB02 2대)
네이밍/통신
- AP01, DB01, DB02 간 HOSTNAME 기반 통신(
ping,nslookup) 확인 - AD(DNS) 또는 hosts로 이름 해석 구조 명확화
방화벽
- AP–DB(필요 시 DB–DB) 간 TCP 135 + (허용한 RPC 포트 정책) 쌍방향 허용
- 테스트:
Test-NetConnection <server> -Port 135
MSDTC 설정(3대 공통)
- Local DTC → Security 탭
- Network DTC Access
- Allow Remote Clients
- Allow Inbound / Allow Outbound
- 환경에 맞는 Authentication 모드 선택
- XA 필요 시 Enable XA Transactions
애플리케이션/DB 테스트
BEGIN DISTRIBUTED TRANSACTION또는TransactionScope로 DB01+DB02 동시 갱신- 실패 시 두 DB 모두 Rollback 되는지 검증(정합성 포인트 포함)
장애(In-doubt) 대비
in-doubt xact resolution기본값(0) 확인- 장애 시 1/2로 일시 변경하는 Runbook 작성
- DMV 조회/증적 절차 문서화 + 최후 수단 KILL(UOW) 절차와 검증 절차 정리

