SimpleIsBest.NET

유경상의 닷넷 블로그
이 글은 오래된 전에 작성된 글입니다. 따라서 최신 버전의 기술에 알맞지 않거나 오류를 유발할 수 있습니다. 저자는 이 글에 대한 질문을 받지 않을 것입니다. 하지만 이 글이 리뉴얼 되면 이 글에 대한 질문을 하거나 토론을 할 수도 있습니다.
닷넷 기반의 시스템에서 분산 트랜잭션 미들웨어로 사용되는 것이 COM+ 이다. 그리고 많은 시스템이 데이터베이스로서 오라클을 사용하고 있다. 종종 COM+ 상에서 오라클과 분산 트랜잭션을 수행할 때 어려움을 겪는 경우가 있다. 이번 포스트는 COM+ 상에서 오라클과 분산 트랜잭션을 수행하기 위해 필수적으로 사용되는 OraMTS에 대해서 살펴보도록 하겠다.

OraMTS :: Oracle Services for MTS

OraMTS 가 무엇일까? OraMTS 가 무엇이며 어떤 역할을 하는가는 고사하고 OraMTS 란 용어 자체를 들어본 적이 없는 독자들이 깨나 있으리라 생각된다. OraMTS는 Oralce Services for Microsoft Transaction Server의 약자로서 오라클 ODAC(Oracle Data Access Component) 혹은 보다 널리 알려진 ODP.NET에 포함되어 있는 모듈을 말한다. 하필 햇갈리게 MTS 냐면, Windows NT 4.0 이 마이크로소프트의 주력 서버 운영체제일 때 개발되어 이름이 OraMTS라 붙었다. 현재 상황에서 MTS = COM+ 로 보아도 큰 무리가 없다. 오라클 버전을 올리면서 이시키의 이름도 OraCOM+ 혹은 OraDTC 정도로 바꾸었으면 하는 바램이 예전 부터 있었지만... 이런 필자의 바램을 그 x 들이 알아 줄리 만무하다. 어찌 되었건,  OraMTS의 주요 역할은 COM+에서 트랜잭션을 관장하는 MSDTC와 더불어 오라클이 분산 트랜잭션에 참여할 수 있도록 해준다. OraMTS는 8.x 버전의 OLEDB 프로바이더 설치 패키지나 9.x, 10.x 버전의 ODP.NET 설치패키지에 포함되어 있으므로, 누구나 무료로 다운로드하고 설치할 수 있다.개략적으로 OraMTS가 무언가 알았으니 이제 좀더 상세한 내용을 디비 보자.

COM+ Transaction : MS-DTC

일부러 컴포넌트의 트랜잭션 속성을 Disabled 혹은 Not Support로 설정해 놓고, Connection 객체의 BeginTransaction 메쏘드를 사용하여  로컬 트랜잭션(혹은 수동 트랜잭션; manual transaction)을 사용하지 않는 한 COM+ 상에서 발생하는 트랜잭션은 분산 트랜잭션이다. 컴포넌트의 트랜잭션 속성에 의해 자동으로 Commit / Abort를 수행해 준다고 해서 자동 트랜잭션(automatic transaction)이라고도 하는 이 트랜잭션의 핵심은 MSDTC 서비스이다. 이 MSDTC 서비스는 OLE 트랜잭션(OLE Transaction) 이라 불리는 COM 기반의 트랜잭션 스펙을 사용하고 있다. 요는 COM+ 상에서 분산 트랜잭션을 지원하려면 OLE 트랜잭션 스펙을 만족하는 모듈을 작성해야 하며 이것이 MSDTC 서비스 상에 로드 되어야 함을 의미한다. 물론 MSDTC가 OLE 트랜잭션 뿐만 아니라 XA 트랜잭션, TIP (Transaction Internet Protocol) 도 지원하지만 가장 기본적인 트랜잭션 프로토콜은 OLE 트랜잭션 이다.

* COM+, MSDTC 와 분산 트랜잭션 (출처 : 월간마이크로소프트웨어 2003년 4월호 .NET 테크니컬 컬럼, 저자: 유경상 (접니다... -_-)

분산 트랜잭션이란 네트워크에 분산되어 있는 자원들에 대해 트랜잭션을 수행하는 것을 말한다. 예를 들어, 어떤 애플리케이션이 SQL 서버와 오라클에 데이터를 트랜잭션 하에서 수행해야 한다면 분산 트랜잭션을 필요로 할 것이다. 대개의 경우 분산 트랜잭션은 턱시도, 티맥스, 엔트라와 같은 TP 모니터나 COM+, EJB 등과 같은 컴포넌트 기반 미들웨어가 그 기능들을 제공한다.

분산 트랜잭션의 반대되는 개념으로서 로컬 트랜잭션은 단일 자원(데이터베이스)에 대한 커밋과 롤백을 수행하며 1-phase 커밋으로서 트랜잭션을 수행한다. 한편 분산 트랜잭션의 핵심은 2-phase 커밋으로 볼 수 있다. 커밋(Commit)과 취소(Abort)(분산 트랜잭션에서는 롤백(rollback)보다는 abort라는 용어를 사용한다)를 수행하는데 두 단계를 거친다는 말이다. 첫 번째 phase는 준비 단계(prepare phase)로서, 데이터베이스는 커밋을 위한 모든 준비를 수행한다. 분산 트랜잭션에 참여한 모든 데이터베이스가 준비 단계를 성공한 후에야 두 번째 phase인 커밋 단계가 수행되는 것이다. 만약 분산 트랜잭션에 참여한 어느 한 데이터베이스라도 준비 단계를 실패한다면 두 번째 phase는 커밋이 아닌 취소를 수행하게 될 것이다.

이렇게 각 데이터베이스에게 준비 혹은 커밋/취소의 두 단계를 수행하도록 트랜잭션을 제어하는 트랜잭션 관리자를 TM (Transaction Manager)이라 부르며 이는 MSDTC(Microsoft Distributed Transaction Coordinator)가 담당한다. 지금까지 단순히 분산 트랜잭션에 참여하는 ‘데이터베이스’라고 참조했지만 데이터베이스 외에 다른 자원들도 분산 트랜잭션에 참여할 수 있다. 대표적인 예로 MSMQ, COM+의 Shared Property가 이에 해당된다. 따라서 분산 트랜잭션에서는 트랜잭션에 참여하는 각 자원에 대한 관리를 맡는 RM(Resource Manager)이 존재한다. RM의 대표적인 예는 오라클, SQL 서버와 같은 데이터베이스를 들 수 있다.

요약해 보면, COM+ 컴포넌트의 분산 트랜잭션의 관리는 MSDTC와 같은 TM을 통해 수행하며 TM은 트랜잭션에 참여한 RM들(SQL 서버, 오라클, MSMQ 등)에게 2-phase 커밋을 수행한다는 점이다. 지금까지의 논의는 대부분 COM+에 관련된 서적이나 MSDN의 플랫폼 SDK를 읽으면 접할 수 있는 내용이다. 따라서 대부분의 독자들이 이 내용을 알고(?) 있으리라 생각한다.

SQL Server와 같은 데이터베이스는 물론 이 OLE 트랜잭션을 기본적으로 지원하고 있다. 따라서 SQL Server 클라이언트가 설치되어 있다면 SQL Server는 DTC 기반 트랜잭션(분산 트랜잭션) 상에서 잘 작동할 것이다. SQL Server 클라이언트 모듈은 MDAC(Microsoft Data Access Component)에 포함되어 있으며, 게다가 MDAC은 운영체제 혹은 IE 설치 패키지에 포함되어 있다. 결론은 SQL Server를 COM+(MSDTC) 상에서 분산 트랜잭션으로 액세스하는데는 별다른 설치도 설정도 해줄 필요가 없다. 물론 MSDTC에 관련된 보안 설정은 수행해 주어야 한다.

MSDTC & OraMTS

OraMTS는 MSDTC가 요구하는 OLE 트랜잭션 프로토콜을 구현하는 오라클 클라이언트의 한 구성요소이다. COM+ 상에서 컴포넌트가 트랜잭션을 요구하고(Requires Transaction 혹은 Requires New Transaction), 오라클을 액세스하면 오라클 클라이언트 API는 OraMTS를 통해 MSDTC의 분산 트랜잭션에 참여(enlist)하게 되는 것이다. 예를 들어, System.Data.OracleClient.OracleConnection 객체가 트랜잭션 속성이 Required 이거나 Requires New 인 컴포넌트에서 Open 되면, OracleConnection 객체는 이 연결을 분산 트랜잭션에 자동으로 enlist 하게 되는 것이다.

다르게 말하면 OraMTS가 없으면 OLE 트랜잭션 프로토콜로는 MSDTC 분산 트랜잭션을 수행할 수 없다는 말이다. 물론 XA 트랜잭션 프로토콜을 통해 MSDTC와 오라클이 분산 트랜잭션을 수행할 수도 있다. MSDTC가 OLE 트랜잭션을 사용할 것인가 아니면 XA 트랜잭션 프로토콜을 사용할 것인가는 순전히 COM+ 컴포넌트가 사용하는 오라클 클라이언트 API에 달려 있다(닷넷에서 오라클을 액세스할 때 사용할 수 있는 다양한 오라클 클라이언트 API에 대한 설명은 지난 닷넷에서 오라클에 접근하는 7가지 방법 포스트를 참고하기 바란다). 다음 표는 오라클 클라이언트 API와 DTC 분산 트랜잭션에서 사용되는 분산 트랜잭션 프로토콜의 종류를 보여준다.

ADO.NET
데이터 프로바이더
네임스페이스 드라이버/프로바이더 분산
트랜잭션 프로토콜
ODBC
Data Provider
System.Data.Odbc Microsoft ODBC for Oracle Driver XA Transaction
Oralce ODBC Driver OLE Transaction (OraMTS)
OLEDB
Data Provider
System.Data.OleDb Microsoft Oracle OLEDB Provider XA Transaction
Oracle OLEDB Provider OLE Transaction (OraMTS)
Managed
Data Provider
for Oracle 1.0
System.Data.OracleClient
(.NET Framework 1.0)
N/A (.NET Native) 지원하지
않음
Managed
Data Provider
for Oracle 1.1
System.Data.OracleClient
(.NET Framework 1.1)
N/A (.NET Native) OLE Transaction (OraMTS)
ODP.NET
Data Provider
Oracle.DataAccess.Client N/A (.NET Native) OLE Transaction (OraMTS)

표 1. 닷넷에서 사용 가능한 오라클 클라이언트 API 및 분산 트랜잭션 프로토콜

위 표를 살펴보면, ODP.NET을 비롯한 오라클에서 제공하는 모든 클라이언트 모듈은 반드시 OraMTS를 사용해야만 COM+ 상에서 분산 트랜잭션을 사용할 수 있도록 되어 있으며 또한 닷넷 프레임워크 1.1 에서 기본으로 제공하는 Data Provider for Oracle (System.Data.OracleClient 네임스페이스) 역시 OraMTS를 요구한다.

OraMTS Architecture

이제 OraMTS 가 어떻게 COM+ 컴포넌트 및 MSDTC와 상호작용하며 오라클 데이터베이스 서버와는 어떻게 상호작용 하는지 알아보자. OTN(Oracle Technology Network)에서 OraMTS에 관련된 기술 자료를 살펴보면 OraMTS의 주요 구성요소와 작동방식을 알아볼 수 있다.


그림 1. Oracle Services for MTS (OraMTS) Components

COM+ 컴포넌트가 트랜잭션을 시작하면 MSDTC는 분산 트랜잭션의 TM(Transaction Manager) 역할을 수행하며, 분산 트랜잭션에 참여하는 RM(Resource Manager)이 트랜잭션의 자원을 관리하게 된다. 이 경우, RM은 오라클 데이터베이스 서버가 된다. 분산 트랜잭션이 시작하면 RM은 트랜잭션에 참여(enlist)해야 하는데, 이때 관여되는 것이 오라클 RM Proxy 이다. 일단 트랜잭션에 참여하면 오라클 RM은 트랜잭션 문맥하에서 데이터베이스가 액세스되도록 하며, 컴포넌트가 트랜잭션을 Commit 하거나 Abort 하면 DTC는 RM Proxy를 통해 오라클 서버에서 트랜잭션을 Commit 하거나 Rollback 하게 되는 것이다.

분산 트랜잭션의 2 phase commit 특성상 RM(오라클 서버)이 트랜잭션의 결과를 알지 못하는 경우가 발생한다. 예를 들어 2 phase commit 수행 도중 준비 단계(prepare phase)를 수행하다가 TM 이 다운되는 경우이다. 이 때 트랜잭션은 결과를 알 수 없는 In-doubt 트랜잭션이 되며 이 트랜잭션을 Commit 하거나 Abort 하는 것은 TM이 다시 수행된 이후에나 가능하게 된다. 오라클은 In-doubt 트랜잭션이 존재하는가를 주기적으로 검사하는 Recovery Job 을 수행한다. 그리고 이러한 In-doubt 트랜잭션이 발생하면 Recovery Job은 OraMTS Recovery 데몬을 통해 DTC와 통신하여 트랜잭션을 Commit 하거나 Abort 하게 된다. (In-doubt 트랜잭션을 Commit 할 것인가 Abort 할 것인가는 어플리케이션마다 다르며, 대개의 경우 트랜잭션을 Abort 하는 것이 일반적이다)

요약하자면, OraMTS는 오라클 RM 프록시와 OraMTS Recovery 데몬을 통해 DTC와 더불어 분산 트랜잭션을 수행하는 것이다. OraMTS를 설치하면 오라클 RM 프록시와 OraMTS Recovery 데몬이 모두 설치된다. 오라클 RM 프록시는 COM+/MSDTC에 의해 런타임에 로드되는 DLL 형태를 갖는다. 사실 RM 프록시는 그림1에서 보는 바와 같이 OraMTS Integration Layer를 통해 로드되는데, 이 DLL이 oramts.dll 이다. Oramts.dll은 COM+상에서 오라클에 대해 트랜잭션이 수행되면 자동으로 로드된다. 따라서 특별한 설정이나 기타의 작업이 전혀 없으며 OraMTS 기반의 트랜잭션을 사용하는 오라클 클라이언트 API(System.Data.OracleClient 혹은 ODP.NET, Oracle OLEDB 등)를 사용하기만 하면 된다. 반면 OraMTS Recover 데몬은 Windows NT 서비스 형태로 설치되는 데몬 프로세스이다. OraMTS를 설치하면 OracleMTSRecoveryService (omtsreco.exe)라는 이름의 서비스가 새로이 설치되는데 이것이 Recovery 데몬이다. 이 프로세스는 서버측의 Recovery Job과 통신하기 위해 TCP 통신을 수행하며 여기에 사용되는 TCP 포트는 디폴트로 2030 번이다. 포트를 수정하기 위해서는 HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\OracleMTSRecoveryService\Protid_0 키의 Port 값을 수정하고 서비스를 다시 시작하면 된다.

Why XA Transaction ?

MSDTC와 호환되는 OraMTS 가 있음에도 불구하고 XA 트랜잭션을 사용하는 오라클 클라이언트 API 가 존재하는 이유가 무언가? 첫째 이유로 오라클 7.x 버전에는 OraMTS 라는 것이 존재하지 않았다. 그리고 그 시기에 마이크로소프트는 MTS/COM+ 상에서 오라클과 분산 트랜잭션을 기능을 제공해야 했었기 때문에 그 당시 오라클의 유일한 분산 트랜잭션 프로토콜인 XA 트랜잭션 프로토콜을 사용했던 것이다. 표 1에서 XA 프로토콜을 사용하는 Microsoft ODBC Driver for Oracle과 Microsoft OLEDB Provider for Oracle이 최초로 등장한 시점에 오라클 버전이 7.x 대 였음을 상기할 필요가 있다.

오라클 8.x 버전이 등장한 이후로도 마이크로소프트의 오라클용 ODBC 드라이버와 OLEDB 프로바이더는 여전히 MSDTC 분산 트랜잭션 프로토콜로 XA 프로토콜을 사용한다. 그 이유는 오라클 8.x 대에 제공되던 OraMTS가 매우 구렸기 때문이다. 8.x 버전의 OraMTS는 OraMTS를 위한 별도의 프로세스를 요구했다(그림 2 참조). 그리고 분산 트랜잭션이 MTS/COM+ 상에서 사용되면 OraMTS 클라이언트 라이브러리가 호출되고 이 라이브러리가 OraMTS 프로세스를 호출하여 분산 트랜잭션에 참여 하였다. 오라클 분산 트랜잭션의 Commit/Abort 역시 OraMTS 프로세스를 반드시 거쳐야 했다.


그림 2. 오라클 8.x 버전의 OraMTS 아키텍처

분산 트랜잭션을 위한 OraMTS가 MTS/COM+와 다른 프로세스상에 존재했기 때문에 오버헤드가 증가 했고, 더욱 나쁜 것은 하나의 오라클 데이터베이스 서버에 오직 하나의 OraMTS 프로세스가 할당되어야 했다. 이 이야기는 여러 개의 분산 트랜잭션 클라이언트가 하나의 오라클 데이터베이스를 사용하는 경우, 모든 트랜잭션 참여 요구와 Commit/Abort는 하나의 OraMTS 프로세스에 집중될 수 있으며, OraMTS가 병목 지점이 될 수 있다는 것이다. 예를 들어 4대의 웹 서버가 오라클을 COM+를 통해 엑세스한다면, 이 4대의 웹 서버는 단일한 OraMTS 프로세스를 호출해야 했다. 이렇게 OraMTS가 병목 지점이 될 수 있기 때문에, 오라클은 안정적인 분산 트랜잭션 서비스를 위해서 OraMTS를 위한 별도의 서버를 준비하는 것이 좋다고 가이드 했었다. 별도의 서버를 준비하더라도 이 서버가 다운되거나 이 서버상의 OraMTS 프로세스가 다운되면 분산 트랜잭션 서비스는 오라클 서버가 멀쩡함에도 불구하고 중단되어야 한다. 이러한 이유로 (사실 마이크로소프트가 OraMTS가 이렇게 구렸다는 이유때문에 XA를 고집했는지는 정확히 알 수 없다) 오라클 8.x 까지는 OraMTS는 찬밥 신세를 면하지 못했던 것이다.

오라클 9.x 에서는 이러한 병목이 존재하지 않는다. RM Proxy는 클라이언트 프로세스(COM+ 컴포넌트가 수행되는 프로세스)와 동일한 프로세스에 로드되며 오라클 데이터베이스 서버 마다 1개의 RM Proxy가 클라이언트 프로세스내에서 구동될 수 있다. 즉, 클라이언트 프로세스가 2개의 오라클 데이터베이스 서버를 OraMTS를 통해 액세스 하면, 프로세스에는 2개의 RM Proxy가 작동한다. 따라서 이전 버전처럼 RM Proxy를 위한 별도의 프로세스나 서버가 필요하지 않게 되었으며 RM Proxy에 문제가 발생하더라도 그 문제는 해당 클라이언트 프로세스에 국한되게 된다.

어찌 되었건 마이크로소프트가 제공하는 오라클용 ODBC 드라이버와, OLEDB 프로바이더는 여전히 XA 프로토콜에 분산 트랜잭션을 의존했으며, 지금까지 변화되지 않았다. 오라클 9.x 버전 이후로 10.x 버전등이 속속 등장했음에도 이들 오라클 클라이언트 API 들이 여전히 XA 에 의존하는 이유는 개발환경 패러다임이 닷넷으로 전환되었기 때문이다. 닷넷 개발환경은 보다 빠른 성능과 오라클 9.x 이상에서 제공하는 데이터타입등을 지원하는 Managed Data Provider for Oracle 1.1을 오라클 액세스의 기본 API로 사용하고 이 API가 OraMTS를 사용하므로 기존 ODBC 드라이버 및 OLEDB 프로바이더를 변경할 이유가 없는 것이다. 하위 호환성을 생각한다면 더욱 더 변경은 불필요한 것이 되어 버린다.

Test !

이제 관련된 테스트를 수행해 보자. 말로만 백날 설명해 봤자 와 닿는게 없으니 실제 분산 트랜잭션을 수행하는 코드를 수행해 보자.

using System;
using 
System.Data;
using 
System.Data.OracleClient;      // Managed Data Provider for Oracle 1.1
using 
System.EnterpriseServices;

class 
SimpleDtcTx
{
    [STAThread]
    
public static void Main()
    {
        
string connStr "User Id=scott;Password=tiger;Data Source=Ora92Test;";
        string 
queryStr "SELECT * FROM EMP";
        
OracleConnection conn = new OracleConnection(connStr);
        
OracleCommand cmd = new OracleCommand(queryStr, conn);
        
OracleDataAdapter adapter = new OracleDataAdapter(cmd);
        
DataSet ds = new DataSet();

        
// COM+ 1.5의 SWC (services without component) 기능을 사용하여
        // 분산 트랜잭션을 사용한다.
        // ServicedComponent를 사용하면 컴포넌트 등록, 서명 등의 귀찮은 작업이 있으므로...
        
ServiceConfig cfg = new ServiceConfig();
        
cfg.Transaction TransactionOption.Required;        // 트랜잭션 속성을 Required로 설정
        
ServiceDomain.Enter(cfg);        // 트랜잭션 시작됨
        
try
        
{
            conn.Open()
;
            
adapter.Fill(ds);
            
ContextUtil.SetComplete();        // Commit에 투표
        
}
        
catch (Exception ex) {
            ContextUtil.SetAbort()
;            // Abort에 투표
            
Console.WriteLine(ex.ToString());
        
}
        
finally {
            
if (conn.State !ConnectionState.Closed) {
                conn.Close()
;
            
}
        }
        ServiceDomain.Leave()
;            // 트랜잭션 종료됨
        
Console.WriteLine("Success !!! Record count = {0}", ds.Tables[0].Rows.Count);
    
}
}
;

위 코드는 닷넷 프레임워크 1.1에 기본으로 포함된 Managed Data Provider for Oracle 1.1 을 사용한 예제코드이다. System.Data.OracleClient 네임스페이스를 사용한 이 코드는 OraMTS가 설치된 상황에서 잘 작동한다. 단순한 조회 쿼리이지만 이 조회는 분산 트랜잭션 문맥하에서 수행된다. 이 코드가 분산 트랜잭션 문맥에서 수행되고 있음을 확인하고자 한다면 구성 요소 관리자 MMC 화면에서 분산 트랜잭션 코디네이터 메뉴의 "트랜잭션 통계" 화면에서 이 코드가 수행될 때마다 "커밋됨" 항목의 개수가 1씩 증가하는 것을 알 수 있을 것이다.

많은 개발자들이 System.Data.OracleClient가 분산 트랜잭션을 지원하지 않는 것으로 알고 있지만 실제로 OraMTS를 통해 COM+ 분산 트랜잭션이 System.Data.OracleClient와 함께 사용될 수 있음을 명확히 보여주고 있다. 위 코드에서 System.Data.OracleClient 네임스페이스 대신 Oracle.DataAccess.Client 네임스페이스를 사용하면 ODP.NET을 통해 오라클을 액세스하게 된다. 물론 ODP.NET을 사용하는 경우 역시 분산 트랜잭션은 잘 작동한다. 한가지 주의할 점은 닷넷 프레임워크 1.0과 함께 사용하는 Managed Data Provider for Oracle 1.0은 OraMTS가 설치되어 있더라도 분산 트랜잭션은 실패한다. 표1에서 보는 바와 같이 이 데이터 프로바이더는 전혀 분산 트랜잭션을 지원하지 않기 때문에, 닷넷 프레임워크 1.0을 사용한다면 OLEDB를 사용하거나 ODP.NET을 사용해야만 분산 트랜잭션을 수행할 수 있다 (관련 자료 : KB322343).

위 코드에서 사용한 ServiceConfig 클래스 및 ServiceDomain 클래스는 COM+ 1.5 버전부터 지원되는 SWC (Services Without Components)라는 기능이다. 간단히 말해 COM+ 컴포넌트를 작성하고 등록하지 않아도 COM+의 트랜잭션과 같은 일부 기능을 사용할 수 있도록 해준다. SWC에 대한 상세한 설명은 월간마이크로소프트웨어 2005년 2월호 테크니컬 컬럼에서 찾아볼 수 있으며 조만간 이 사이트에도 HTML 화하여 게시될 것이다(참고로 위 코드는 Windows XP SP2 이상 그리고 Windows 2003에서만 작동한다).

만약 OraMTS가 설치되지 않은 상황에서 위 코드를 수행하면 닷넷 프레임워크는 oramts.dll을 찾을 수 없다는 예외(unable to load 'oramts.dll') 혹은 초기화를 실패했다는 예외를 발생할 것이다(OraMTS 버전에 따라서 다를 것임). 이는 닷넷이 기본으로 제공하는 Managed Data Provider for Oracle 1.1이 OraMTS에 의존하고 있음을 분명히 보여준다. ODP.NET 이나 Oracle OLEDB Data Provider, Oracle ODBC Driver 역시 모두 분산 트랜잭션을 위해서는 OraMTS를 필요로 한다. OraMTS가 설치되어 있지 않은 경우에 이들 클라이언트 API는 모두 분산 트랜잭션을 실패할 것이다.

Summary

요약해 보자. OraMTS는 COM+ 상에서 트랜잭션을 사용하기 위해 주요 클라이언트 API 들이 사용하는 핵심적인 구성요소이며 OraMTS를 통해 MS-DTC는 오라클 데이터베이스 서버와 분산 트랜잭션을 수행할 수 있다. System.Data.OracleClient 네임스페이스를 사용하는 Managed Data Provider for Oracle 1.1 도 역시 OraMTS를 통해 오라클과 함께 분산 트랜잭션을 수행할 수 있으며, 오라클에서 제공되는 닷넷 데이터 프로바이더인 ODP.NET, Oracle OLEDB Provider, Oracle ODBC Driver 모두 COM+ 분산 트랜잭션을 위해 OraMTS를 필요로 함을 기억해 두자.

쓰바... 간단히 쓴다는 것이 그림을 2개나 그리고 짧지 않은 예제 코드까지 짰다... 낼 일찍 출근해야 하는데 새벽 2시다... 쓰바 조되따... -_-



Comments (read-only)
#[질문] 과연 dtc가 odp.net과 제대로 분산트랜젹션을 지원하는지... / 운비 / 9/7/2005 12:31:00 AM
우선, 이곳이 질문해도 되는 곳인지 궁금하고 그게 아니라면 정말 죄송합니다.

환경--
웹서버 os는 2003 sp1 이고, 디비서버는 2003 sp1, oracle 10g, 기간계디비서버는 유닉스 oracle 10g입니다
웹서버의 dtc 보안설정은 아티클에 있는 설정과 같습니다.

틀린점은 웹서버와 디비서버간 host파일설정은 안한 상태이고, 상호인증에 체크가 되어있는 점이 틀리군요

이럴때, 현재 biz com은 required로 설정이 되어있고, 디비서버에 트랜잭션수행은 잘되어집니다. 문제는 하나의 sp에서
디비서버에 인서트할때, 뷰테이블을 특정데이터를 참조하여 넣는데 뷰테이블은 기간계디비서버로 디비링크를 통해 가져옵니다. 이상황에서는 디비연결이 새로운 트랜잭션을 사용한다는 디비연결에러 혹은 root트랜잭션이 제대로 commit 혹은 abort가 되지 않는다는 에러가 발생합니다. 또 다른 상황은 하나의 sp에서 디비서버에 인서트후 기간계디비서버로 디비링크를 통해 인서트시 연결에러(새로운 트랜젝션)가 납니다

bizTx(Required)를 supported 나 not supported로 설정시, 위와 같은 문제는 생기지 않으며, not supported로는 테스트를
못해보았으나 supported로 설정시 에러발생하면 롤백이 되었습니다.

이와 같은 현상으로 해서 설정문제인지 oraMts문제인지 점점 모호해지고..oramts가 과연 dtc프로세스와 같이 움직이는지
의구심마저 드는 상황인지라...위에 글은 그런 혼란속에 개념적으로 도움이 되었습니다. 하지만 여전히 궁금한 점에 대해 물어보지 않을 수가 없네요..


질문 1. 호스트파일설정과 상호인증을 사용안하면 제대로 수행이 될까요?
질문 2. 디비서버는 곧 유닉스로 전환될 예정이죠...이럴때 dtc설정을 어떻게 해야 할까요?

의문 1. 우선 호스트파일에 웹서버(dtc) 와 디비서버(mssql dtc)간의 통신은 ip통신입니다. 그러나 일반적인 os통신은
말씀하신대로 넷바이오스 통신이죠 따라서 디비서버와 웹서버간의 dtc통신은 ip로 찾아야 하는데 실제로 컴이름 찾으려니
안되니깐 호스트파일을 이용하겠죠...그렇다면, 윈2003웹서버와 유닉스 디비서버간의 dtc통신은 ...oraMts 혹은 서비스(웹서버에 설치된)가 담당하지 않을까요?..그렇다면 호스트간 설정은 무의미하지 않을까....이런 의문이 생기네요..
어떨까요?

의문2. 윈2003과 유닉스 디비서버간에 rpc상호인증은 따라서 당연히?...무의미 한것인가?...

종합 질문 odp.net을 이용한 Oracle.DataAccess.Client을 사용시 위 환경하에서 분산트랜젝션을 제대로 수행하기 위한 방법이 궁급합니다.

다시한번 질문글을 올리게 되어 죄송합니다.
기회가 되어 이글을 읽게되시면 조언좀 부탁드립니다.
#re: COM+ 트랜잭션과 오라클 :: OraMTS 의 실체 / 블로그 쥔장 / 9/7/2005 8:05:00 PM
먼저 오라클과 DTC와의 분산 설정은 RPC와 전혀 상관이 없습니다.
웹서버 혹은 어플리케이션 서버(즉, COM+가 수행 중인 서버)의 DTC가 SQL Server와 분산 트랜잭션을 수행할 때에만
SQL Server가 존재하는 서버의 DTC와 어플리케이션 서버의 DTC가 통신하는 것이며 이 통신에 RPC가 사용되는 것입니다.

DTC와 오라클이 분산 트랜잭션에 관여될 때는 항상 DTC가 수행되는 서버에 설치된 OraMTS.dll이 관여됩니다.
고로 hosts 파일이니 RPC니 하는 것들이 전혀 상관이 없게 되어 버리는 것이지요.
DTC가 오라클하고만 분산 트랜잭션을 수행하고 오라클과의 접속이 ODP.NET 혹은 Managed Data Provider for Oracle 이라면
DTC의 보안 설정은 거의 상관이 없게됩니다. 상호 인증이니 머니 이딴게 필요 없는 것이지요.

오라클이 유닉스 서버에 존재하건 Windows 서버에 존재하건 DTC 설정이 달라질 건 없습니다.
DTC의 보안 설정 역시 건드려 줄 필요가 거의 없습니다. DTC의 보안 설정은 2개 이상의 DTC가 분산 트랜잭션에
참여할 때에만 고려해야 할 사항이며, 오라클의 경우 어플리케이션 서버의 DTC는 Oramts.dll 을 통해
곧바로 오라클과 통신합니다. (오라클 서버측의 DTC와 무관하다는 것이지요. 사실 UNIX에는 DTC란 것이
존재하지도 않습니다)

트랜잭션상에서 오류를 말씀하셨는데, 대부분의 트랜잭션이 제대로 작동하지만
SP내에서 디비링크를 참조할 때 오류가 발생하는 것 처럼 보입니다만...

만약 그렇다면 그것은 COM+에 의해 시작된 분산 트랜잭션 내에서 Windows 상의 오라클이
Unix 상의 오라클과 또 다른 트랜잭션을 맺을려고 하는 것 같은데요...
이 경우, DTC 트랜잭션이 아닌, 오라클 서버대 오라클 서버의 트랜잭션이 될 가능성이 농후합니다.
이러한 오라클대 오라클의 트랜잭션에서 사용되는 분산 트랜잭션의 프로토콜은
XA 프로토콜일 가능성이 높습니다(오라클 전문가가 아니라 확인은 못해드리겠네요... -_-)
XA 프로토콜에 분산 트랜잭션이 수행되는 경우, Unix 서버의 계정에 XA 에 관련된 몇 몇 뷰에 대한
권한 설정이 필요합니다. 그 부분을 확인해 보시기 바랍니다.

도움이 되셨기를....