현재 우리나라에서 가장 많이 사용되는 데이터베이스를 꼽으라면 오라클, MS SQL Server, DB2 정도를 꼽을 수 있을 겁니다. 닷넷 플랫폼에서 데이터베이스 사용 역시 오라클 혹은 MS SQL Server 가 가장 많이 사용되는 데이터베이스일 겁니다. 그래서 닷넷에서 오라클 데이터베이스에 연결하는 방법에 대해서 씨리즈를 작성해 보려고 합니다. 귀차니즘으로 인해 여러 회의 포스트로 나누어 작성할 것이니 이해 바랍니다.

Connecting Oracle

오라클... 이름 하나는 끝내주게 멋진 데이터베이스다. 개인적으로 필자는 오라클을 좋아하지 않는다. 웬지 모르는 위압감, 기득권자로서의 행태, PC에 쉽게 설치하고 테스트하기 어려움, 열받게 많이 설치되는 기타 요소들(특히 지맘대로 설치되는 자바 런타임), 기타 등등...

그래도 국내에서 가장 많이 사용되고 있는 데이터베이스인지라 닷넷 플랫폼에서 오라클 데이터베이스에 접근해야 할 상황이 아주 많이 발생되곤 한다. 싫건 좋건 오라클을 써야 하는 것이다. 그런데 문제는... 닷넷에서 오라클에 접속하여 사용하는 방법이 졸라 많다는 것이다. 메이저 데이터베이스이다 보니 마이크로소프트에서까지 오라클 관련 ODBC 드라이버, OLEDB 프로바이더, ADO.NET 프로바이더를 제공하고, 당근 빠따로 오라클에서 제공하는 ODBC 드라이버, OLEDB 프로바이더, ADO.NET 프로바이더가 존재하고 써드 파티 제조 업체까지 이런 드라이버, 프로바이더를 제공하니 모두를 조합하면 10가지가 훨씬 넘어가버린다.

그래서... 닷넷에서 오라클 접속을 위한 여러 가지 설정을 정리하고자 한다. 단순한 오라클 접속 뿐만 아니라 COM+에서 분산 트랜잭션을 사용하기 위한 설정까지를 설명할 것이다(다음 포스트가 될 것 같다). 모든 오라클 접근 방법을 다 설명하자면 너무 빡센 관계로 가장 많이 사용되는 Microsoft 드라이버/프로바이더와 오라클 드라이버/프로바이더를 사용하는 방법만을 기술하고자 한다.

참고로... 필자는 오라클 전문가가 아니다. 다만 닷넷의 관점에서 필요한 설치 혹은 설정만을 기술하는 것이므로 접속이 되네 안 되네를 가지고 필자에게 따지지 말기를...

Baseline Setting

오라클에 접속하기 위해서는 반드시 필요한 요소는 오라클 클라이언트라 불리는 설치 패키지이다. 오라클 클라이언트를 죄다 설치할 필요는 없다. 오라클에 접속하여 사용하기 위해서는 반드시 OCI(Oracle Client Interface)를 사용해야 하고 이 OCI는 네트워크 프로토콜로서 오라클의 SQL*Net을 사용한다. 따라서 오라클 클라이언트 설치 요소 중, OCI와 SQL*Net을 설치해야 한다.

일부 무지 몽매한 사람들이 오라클 ODBC/OLEDB 만 달랑 설치하고 오라클에 접속이 안된다는 사람들이 있어서 설명하는 것이다. 최소한 OCI와 SQL*Net이 설치된 상황에서 ODBC를 쓰던 OLEDB를 쓰던 ADO.NET 할아버지를 쓰던 해야만 오라클에 접속할 수 있다.

이렇게 설치가 끝나면 TNS 설정을 해야 한다. TNS 파일을 직접 수정하던 UI 유틸리티를 사용하건 TNS 설정을 정확하게 잡고 테스트를 수행해야 한다. 닷넷에서 접속이 되는가를 테스트하기 전에 TNS 설정이 유효한가를 반드시 먼저 확인하도록 하자.

또한 COM+에서 오라클을 액세스하는 분산 트랜잭션을 사용한다면 반드시 Oracle Services for Microsoft Transaction Server (OraMTS)를 설치해야만 한다. OraMTS는 오라클 클라이언트 버전 9.2 (ODP.NET 9.2) 이상에서 COM+ 기반 트랜잭션(MS-DTC 기반 트랜잭션)을 오라클과 함께 수행하기 위해 반드시 필요한 요소이다. OraMTS는 ODP.NET 설치시 기본적으로 설치가 선택되어 있으므로 눈 찔금 감고 설치하면 된다. (오라클 클라이언트 8.1.x 에도 OraMTS는 포함되지만 문제가 많아서 사용되지 않았었다)

Connectivity Methods

닷넷 플랫폼에서 오라클에 접속하는 다양한 방법을 정리해 보자. 정리하는 방법은 ADO.NET의 닷넷 데이터 프로바이더의 종류에 의해 구분을 해보자.

ADO.NET
데이터 프로바이더
네임스페이스드라이버/프로바이더사용빈도*성능**분산
트랜잭션***
ODBC
Data Provider
System.Data.OdbcMicrosoft ODBC for Oracle Driver낮음좋지 않음XA
Oralce ODBC Driver낮음보통OraMTS
3rd Party ODBC Driver극히 낮음??
OLEDB
Data Provider
System.Data.OleDbMicrosoft Oracle OLEDB Provider낮음좋지 않음XA
Oracle OLEDB Provider보통보통OraMTS
3rd Party OLEDB Provider???
Managed
Data Provider
for Oracle 1.0
System.Data.OracleClientN/A (.NET Native)낮음보통지원하지
않음
Managed
Data Provider
for Oracle 1.1
System.Data.OracleClientN/A (.NET Native)높음좋음OraMTS
ODP.NET
Data Provider
Oracle.DataAccess.ClientN/A (.NET Native)높음좋음OraMTS
3rd Party
Data Provider
N/A (product specific)N/A (.NET Native)알 수 없음알 수 없음?

* 사용빈도는 필자의 경험상 닷넷 프로젝트들에서 선호되는 오라클 액세스 방법을 표시한 것이다. 객관적인 통계 자료에 의해 산출된 것이 아님에 유의하기 바란다. (좀 무책임하게 말해서 믿거나 말거나란 소리다. -_-)
** 성능은 필자가 직접 테스트한 결과가 아니라 프로젝트에서 경험적으로 취득한 것이거나 해당 접속 방법을 사용한 프로젝트 관계자로부터 전해 들은 것을 기록한 것이다. 또한 절대적인 성능이 아닌 다른 데이터 엑새스 방법에 상대적인 성능이다.
*** COM+(MS-DTC) 기반의 분산 트랜잭션 지원 여부이며 XA는 XA 프로토콜을 통한 분산 트랜잭션을, OraMTS는 오라클에 포함된 Oracle Service for Microsoft Transaction Server 를 통한 분산 트랜잭션 지원을 의미한다.

위 표를 보면 닷넷 데이터 프로바이더에 따라서 ODBC 데이터 프로바이더(System.Data.Odbc)를 사용하는 경우와 OLEDB 데이터 프로바이더(System.Data.OleDb)를 사용하는 경우, 그리고 오라클 네이티브 데이터 프로바이더 들이 존재한다. 오라클 네이티브 프로바이더들은 직접 OCI 레벨을 액세스하는 수준이므로 관계가 없지만(그림 1 참조), ODBC와 OLEDB는 또 다른 API 스택을 거치게 되므로 어떤 드라이버/OLEDB 프로바이더를 사용하는 가에 따라서 오라클 접근 방법이 차이가 나게 된다(그림 2 참조). 그래서 별도로 구분하여 표기하였다.


그림 1. ADO.NET 네이티브 프로바이더를 통한 오라클 액세스

Managed Data Provider for Oracle에 대해서 이야기를 하자면, 닷넷 프레임워크 1.0이 나왔을 때 오라클을 위한 닷넷 데이터 프로바이더는 존재하지 않았다. 그래서 몇 개월 후 별도 애드인 성격으로 Managed Data Provider for Oracle를 다운로드 하여 설치할 수 있었던 것이다. 이후 닷넷 프레임워크 1.1이 나오면서 별도로 설치되던 이 프로바이더를 닷넷 프레임워크 안에 포함시켰다. 따라서 닷넷 프레임워크 1.0은 별도로 Managed Data Provider for Oracle을 설치해야 하며, 닷넷 프레임워크 1.1은 별도 설치를 하지 않아도 된다. 이 둘을 구분하기 위해 버전 1.0, 1.1로 구분하기도 하고 특별히 구분하지 않고 닷넷 프레임워크 1.0용 Data Provider For Oracle, 닷넷 프레임워크 1.1 용 Data Provider for Oracle 이라 칭하기도 한다.

이 두 버전은 클래스, 메쏘드, 기타 기능상의 차이는 없다. 다만 다른 점은 Data Provider for Oracle 1.0은 분산 트랜잭션을 지원하지 않는다. 즉, COM+ 상에서 이 프로바이더를 사용하여 트랜잭션을 수행하면 다음과 같은 InvalidOperationException 메시지를 보게 될 것이다.

Failed to initialize distributed transactions. Please see KB article Q322343

물론 1.1 버전의 데이터 프로바이더는 분산 트랜잭션을 지원한다.


그림 2. ADO.NET OLEDB Provider와 ODBC Provider를 통한 오라클 액세스

써드 파티의 닷넷 데이터 프로바이더와 ODBC, OLEDB 프로바이더는 제작사에 따라서 네임스페이스나 특성이 각각 상이하고 필자가 사용해본 경험 또한 없으며 사용되는 것을 본 적 또한 없다. 그래서 앞으로의 기술에서 이들은 제외하겠다. 이렇게만 보아도 7 가지의 접근 방법이 나온다.

  • Odbc 데이터 프로바이더 사용 (Microsoft ODBC for Oracle 드라이버 이용)
  • Odbc 데이터 프로바이더 사용 (Oralce ODBC 드라이버 이용)
  • OleDb 데이터 프로바이더 사용 (Microsoft OLEDB Provider 이용)
  • OleDb 데이터 프로바이더 사용 (Oracle OLEDB Provider 이용)
  • Oralce 데이터 프로바이더 사용 (.NET Framework 1.0 버전)
  • Oracle 데이터 프로바이더 사용 (.NET Framework 1.1 버전)
  • ODP.NET 데이터 프로바이더 사용 (Oralce.DataAccess.Client 이용)
  • 이제 이들 접근 방법들에 대해 간략히 살펴보도록 하자. 다시 한번 강조하겠지만 이 글에서 다루는 각 오라클 접근 방법의 장단점은 테스트를 통해 얻은 결과라기 보다는 필자의 경험과 주위의 조언/경험담에서 나온 것임에 유의할 필요가 있다. 쉽게 말하자면 보증이 없으니 알아서 판단하라는 얘기이다. 나중에 필자에게 와서 씨바 이시키 사기쳤다고 꼬장 부리는 일이 없기를 바란다....(필자가 시간과 여러 대의 서버, 그리고 중요한 돈이 있으면 이런 거 다 테스트 해볼 텐데... 누구 스폰서 없나 아쉬울 따름이다)

    Using ODBC Data Provider

    ODBC 데이터 프로바이더는 System.Data.Odbc 네임스페이스의 클래스들을 사용하며, ODBC 드라이버를 명시해 주어야 한다(DSN을 명시하는 것을 기억하자). 이 때 사용할 수 있는 ODBC 드라이버들이 마이크로소프트가 제공하는 것과 오라클이 제공하는 것 중 하나를 사용할 수 있다는 것이 되겠다(그림 2 참조).

    마이크로소프트의 ODBC 드라이버는 MDAC 2.x (이전 버전에도 포함된 것으로 알고 있다)에 포함되어 있다. MDAC는 운영체제와 같이 설치되므로 기본적으로 사용할 수 있다. 하지만 KB244661 에서 명시하는 바와 같이 이 드라이버는 레퍼런스 커서나 CLOB, BLOB, NVARCHAR2 데이터 타입에 대한 지원들이 전혀 없거나 상당히 약한 것으로 알려져 있다. 결정적으로 이 프로바이더는 Unicode, UTF8과 같은 다국어를 제대로 지원하지 않는다. 또한 이 드라이버는 오래 전에 업그레이드가 중지되었고 더 이상 지원도 되지 않는 것으로 알고 있다. 마이크로소프트는 이 드라이버가 '안정적'인 상태이고 새로운 데이터 액세스(ADO.NET Data Provider) 기법이 존재하기 때문에 업그레이드나 지원을 하지 않는다고 한다.

    오라클의 ODBC 드라이버는 ODP.NET 패키지나 오라클 클라이언트 패키지 내에 존재한다. 따라서 별도로 설치해야만 하는 ODBC 드라이버가 되겠다. 오라클 서버의 버전이 업그레드 됨에 따라 이 드라이버도 계속 업그레이드 되고 있으며, 고로 오라클이 제공하는 특별한 기능, 데이터 타입을 모두 지원한다. 아니 지원 하는 것으로 알고 있다. (써보질 않아서... 바로 비굴 모드로... -_-)

    Using OLEDB Data Provider

    닷넷에서 OLEDB 데이터 프로바이더를 사용한다는 말은 System.Data.OleDb 네임스페이스의 클래스들을 사용한다는 말이다. ODBC의 경우와 비슷하게 닷넷 OLEDB 데이터 프로바이더는 OLEDB 프로바이더를 연결 문자열에 명시해야 한다(Provider=xxxx 이렇게 말이다). 마찬가지로 마이크로소프트가 제공하는 OLEDB 프로바이더((MSDAORA)와 오라클이 제공하는 OLEDB 프로바이더(OraOLEDB.Oracle) 두 가지가 많이 사용된다(그림 2 참조).

    마이크로소프트의 OLEDB 프로바이더 역시 MDAC 2.x 에 포함되어 있다. 닷넷이 발표되기 전에 가장 많이 사용되었으며 이제는 그다지 많이 사용되지 않고 있다. ODBC 드라이버와 마찬가지로 이 OLEDB 프로바이더 역시 '안정적'인 상태로 분류되어 더 이상 업그레이드나 지원이 되고 있지 않는 것으로 알려져 있으며 KB244661 에서 명시하는 제약 사항을 갖고 있다. 이 OLEDB Provider 를 사용하면 COM+ 트랜잭션에서 특이하게도 XA 트랜잭션(분산 트랜잭션 프로토콜로 XA 프로토콜을 사용함)을 통해 오라클과 트랜잭션을 수행한다. 이를 위해 오라클 서버와 레지스트리에 몇 가지 설정이 수행되어야만 한다. 왜 이 녀석이 XA를 사용하는지 그리고 어떤 설정을 해줘야 하는지는 다음 기회에 다루기로 하고, 여기서는 이 정도만 알아 두자. 참고로 마이크로소프트에서 제공하는 오라클 ODBC 드라이버가 COM+ 트랜잭션에서 사용될 때 역시 XA 프로토콜이 적용된다.

    오라클에서 제공하는 OLEDB 프로바이더는 ODBC와 마찬가지로 ODP.NET 패키지나 오라클 클라이언트 패키지에 포함되어 있다. 8.x 버전에는 별도로 오라클 OLEDB 프로바이더를 다운로드 할 수 있었지만, 지금은 ODP.NET 패키지만 포함되어 있다. ODBC의 경우 처럼 이 녀석도 서버 버전과 맞추어 버전 업되고 있다. 당연하게 오라클의 새로운 기능들을 모두 수용한다. 닷넷이 아닌 환경에서 오라클을 액세스 한다면 대부분 이 OLEDB 프로바이더를 통해 오라클을 액세스 할 것이다. 성능적인 측면에서는 오라클의 OLEDB 프로바이더가 마이크로소프트의 그것보다 낫다고 하며, 데이터베이스 제조사가 만든 OLEDB 프로바이더니까 당연히 그래야 할 것이다.

    Using Microsoft Data Provider for Oracle

    마이크로소프트에서 제공하는 닷넷용 오라클 프로바이더는 괴씸하게도 두 개이다. 첫 번째는 닷넷 프레임워크 1.0이 발표된 직후 등장한 Managed Data Provider for Oracle 이란 녀석인데 애드인 성격으로 별도 설치를 해야만 한다. SQL-Server용 ADO.NET 데이터 프로바이더처럼 오라클 전용의 닷넷 네이티브 데이터 프로바이더가 되겠다.

    Managed Data Provider for Oracle 이 녀석은 OLEDB 데이터 프로바이더를 통해 오라클을 액세스하는 것 보다 더 다양한 기능들과 보다 닷넷 스러운 클래스들을 갖고 있으며 오라클의 다양한 기능들을 지원한다. 하지만 모든 오라클 데이터 타입, 기능을 지원하는 것은 아니다. 또한 Managed Data Provider for Oracle의 가장 큰 문제는 COM+ 트랜잭션을 전혀 지원하지 않는다는 것이다. 이 녀석이 COM+ 트랜잭션 내에서 사용되면 여지없이 Exception 이 발생하며, COM+(MS-DTC)를 지원하지 않는다는 메시지가 나타난다.

    닷넷 프레임워크 1.1이 등장하면서 이전 버전의 오라클 데이터 프로바이더가 프레임워크 내부로 포함되었다. 이전 버전과 구분하기 위해 Managed Data Provider for Oracle 1.1 이라고 명명하거나, 그냥 아무런 지칭 없이 Data Provider for Oracle이라고 하면 닷넷 프레임워크 1.1에 포함된 오라클용 데이터 프로바이더라고 생각하면 되겠다. System.Data.OracleClient 네임스페이스에 존재하는 클래스들이 그것들 인데, 클래스와 메쏘드들은 거의 변화사항이 없지만 성능이 더 나아졌다고 하며(마이크로소프트의 주장이다), 이제는 COM+ 트랜잭션도 이젠 지원 된다(이것을 모르는 사람들이 예상외로 많았다). 닷넷 프레임워크 1.1 내에 포함되어 있으므로 별도의 설치가 필요하지 않다는 장점도 갖는다.

    오라클 데이터 프로바이더는 성능면에서나 API의 사용법, COM+ 지원 등에서 보았을 때 사용상에 큰 문제가 없다. OLEDB 프로바이더와 다르게 BLOB, CLOB, NVARCHAR2 등 일반적인 어플리케이션에서 사용되는 대부분의 데이터 타입을 제대로 지원하며, 유니코드 등도 모두 지원한다. 별다른 이유가 없다면 Managed Data Provider for Oracle 1.1 을 통해 오라클을 액세스하는 것은 좋은 선택이 될 것이다. (버그 리포트가 심심치 않게 보이지만... 선택은 자유임다... 텨텨텨~~~)

    Using ODP.NET

    일반적으로 ODP.NET 이라 불리는 오라클이 제공하는 ADO.NET 데이터 프로바이더는 최근 닷넷 환경에서 가장 많이 사용되는 오라클 액세스 방법 중 하나일 것이다. 오라클에서 제공하는 닷넷 네이티프 프로바이더이기 때문에 가장 빠르게 오라클 서버를 액세스하며, 오라클 서버가 제공하는 모든 데이터 타입을 지원한다. 몇몇 버그 리포트가 보이긴 하지만 세상에 버그 없는 프로그램이 있던가?

    앞서 언급한 마이크로소프트 ADO.NET 데이터 프로바이더(System.Data.OracleClient)가 COM+를 지원한다는 사실을 모를때 COM+에서 유일한 대안이기도 했던 이 녀석은 최근 오라클이 닷넷 환경에 대한 지원을 많이 수행함에 따라 더욱 관심을 많이 갖게 되었다. 오라클 데이터베이스를 사용하는 많은 닷넷 프로젝트들이 ODP.NET 데이터 프로바이더를 통해 오라클을 액세스하고 있으며, 앞으로도 대세가 되지 않을까 싶다. 아무래도 벤더가 직접 만든 것이니까 뭐가 좋아도 좋다는 막연한 기대감과 구체적인 성능 비교를 해보지도 않고 ODP.NET이 더 빠르다는 미신이 떠돌면서 많이 사용되는 것 같다.

    비공식적인 ODP.NET과 마이크로소프트 오라클 데이터 프로바이더의 성능 비교에서 둘의 차이는 거의 없었다고 한다. 하지만 오라클의 최신 버전에서 제공하는 특별한 데이터 타입을 사용해야 하거나 레퍼런스 커서에 대한 지원이 필수적이라면 ODP.NET을 선택할 수 밖에 없을 것이다. 닷넷 프레임워크 1.1의 오라클 데이터 프로바이더와 ODP.NET의 오라클 데이터 프로바이더에 대한 비교 자료는 다음 MSDN 기술 자료에서 찾아 볼 수 있다. 이 자료는 ODP.NET Data Provider와 Data Provider for Oracle (1.1)로 CLOB, BLOB 등의 데이터 타입을 액세스하는 구체적인 방법 또한 다루고 있으니 "잉글리쉬 커뮤니케이션에 핸디캡이 노" 한 사람은 한 번쯤 읽어보는 것이 좋다.

    Comparing the Microsoft .NET Framework 1.1 Data Provider for Oracle and the Oracle Data Provider for .NET

    Which One ?

    지금까지 나열한 7가지 방법 중에 어떤 것을 써야 할까?

    "꼴린 대로 하시오..."

    이렇게 답변하면 맞아 죽을 터이니... 필자의 의견을 말해 보겠다.

    성능적으로 보았을 때나 닷넷 환경에서의 데이터 액세스 기법을 고려했을 때 ADO.NET의 네이티브 데이터 프로바이더를 사용하는 것이 가장 좋다. 고로 ODBC, OLEDB 는 빠지게 되겠다. 3가지의 네이티브 프로바이더 중 COM+ 지원이 아리까리한 Managed Data Provider for Oracle 1.0을 제외 하자. 남은 건 ODP.NET 데이터 프로바이더 이냐 아니면 마이크로소프트 오라클 데이터 프로바이더(Data Provider For Oracle 1.1) 이냐만 결정하면 된다. 이 두 가지 중 하나를 고르는 건 정말 꼴린대로 하면 된다.

    필자의 의견으로 이 둘 중 어느 것을 사용해도 무방할 것 같다. 오라클 9i, 10g 에서 새로이 추가된 특별한 기능을 반드시 사용해야만 하는 경우가 아니라면 더욱더 둘 중에 아무것이나 써도 된다. 그렇지 않다면 ODP.NET 쪽에 무게가 조금 더 실린다.

    만약 닷넷 프레임워크 1.0 기반에 COM+를 사용한다면 대안은 ODP.NET 이 되겠다. 혹, 닷넷 OLEDB 데이터 프로바이더 + 오라클 OLEDB 프로바이더의 조합도 1.0 상황이라면 나쁘지 않다. 하지만 여전히 닷넷 네이티브 데이터 프로바이더인 ODP.NET을 쓰는 것이 성능적인 관점에서 좋다고 말할 수 있겠다.

    여기까지가 필자의 의견이다. 필자 의견이 맘에 들지 않거나 다른 의견이 있다면 잽싸게 피드백 해주기 바란다.

    What's Next ?

    다음 포스트에는 COM+ 트랜잭션 상에서 오라클을 사용하는 방법에 대해 썰을 풀도록 하겠다. 왜 마이크로소프트 ODBC 드라이버와 OLEDB 프로바이더가 XA 트랜잭션을 썼어야 했는지, 그리고 그 설정 방법은 무엇인지, 그리고 COM+ 트랜잭션에서 닷넷 네이티브 데이터 프로바이더들이 사용될 때 필요한 것이 무엇인지 간략(?)하게 글을 쓰려고 생각하고 있다.

    너무 기대를 많이 하진 않는 것이 좋겠다. 필자가 워낙 게을러서... 우헐헐...