본 장에서는 트랜잭션의 개념과 정의 및 처리 방법을 설명한다.
트랜잭션은 자원을 하나의 일관된 상태에서 다른 일관된 상태로 변화시키는 일의 단위이다.
Tmax는 로컬 트랜잭션과 전역 트랜잭션을 지원한다.
Tmax의 트랜잭션 처리는 ACID(Atomicity, Consistence, Isolation, Durability) 속성을 지키며 작업을 처리한다. 트랜잭션 처리와 관련된 표준으로 X/Open DTP 모델의 TX 규격을 따른다.
ACID의 특성은 다음과 같다.
일이 완전히 수행되거나 전혀 수행되지 않는(all or nothing) 2가지 경우만 존재해야 한다.
트랜잭션의 성공적인 수행결과를 하나의 일관된 상태에서 다른 일관된 상태의 공유자원에 갱신한다.
공유자원을 바꿀 때 트랜잭션의 결과가 commit이 될 때까지 트랜잭션 외부로 나타나지 않는다.
하위 시스템이나 media 오류를 거친 트랜잭션 commit의 결과를 바꾼다. 성공적으로 완료된 트랜잭션의 결과는 영구적으로 반영된다.
전역 트랜잭션은 둘 이상의 동종 및 이종의 데이터베이스가 관련된 전역 트랜잭션에서는 트랜잭션의 속성을 보장하기 위해 2PC(2 Phase Commit)를 사용한다. 2PC란 둘 이상의 데이터베이스가 연동할 때 ACID 속성을 완전히 보장하기 위해 2단계 처리(Prepare 단계, Commit 단계)를 하는 것을 말한다.
분산 트랜잭션을 처리할 경우 2단계 Commit을 지원하여 데이터 무결성(Integrity)을 보장하고 간단한 몇 가지 함수(tx_begin, tx_commit, tx_rollback 등)를 제공하여 전역 트랜잭션을 용이하게 한다. 또한 Multithread 방식의 트랜잭션 매니저를 제공하여 적은 자원 대비 효율성을 제공하고 동적 로깅으로 에러가 발생하는 경우 신속히 대응하므로 Recovery/Rollback에 의한 안정성을 보장한다. 모든 트랜잭션은 중앙에서 관리하므로 트랜잭션에 대한 스케줄링이나 관리가 용이하다.
Tmax의 분산 트랜잭션 처리 방식은 기본적으로 국제 표준인 X/Open의 모델(DTP)을 기반으로 한다. X/OPEN DTP를 준수하는 표준 함수의 집합체인 X/OPEN ATMI를 따른다.
다음은 X/Open DTP의 구조이다.
다음은 X/Open DTP의 구성요소에 대한 설명이다.
X/OPEN ATMI는 X/OPEN DTP를 준수하는 서로 다른 종류의 DBMS 사이에 발생하는 트랜잭션을 묶어서 처리한다. 다음은 분산 트랜잭션의 처리 과정에 대한 설명이다.
트랜잭션은 tx_begin()을 호출해서 tx_commit() 또는 tx_rollback()이 호출되는 부분까지이다.
tx_begin()은 트랜잭션을 시작하게 하며, 이 함수를 부른 프로세스는 트랜잭션 게시자가 된다. 트랜잭션 게시자는 tx_commit() 또는 tx_rollback()을 호출하여 트랜잭션을 완결하여야 할 의무를 지닌다. tx_begin()으로 시작하여 tx_commit() 또는 tx_rollback()으로 완결되는 하나의 트랜잭션에 포함되는 프로세스들을 트랜잭션 참여자(participant)라 부르며, 트랜잭션 참여자들은 tpreturn()으로 반환하는 값에 의해서 트랜잭션의 결과에 영향을 줄 수 있다. 트랜잭션 상태에서 tx_begin()으로 다시 트랜잭션을 시작하려고 할 경우 이는 실패되며, tperrno에 TPEPROTO가 설정된다. 그러나 원래 트랜잭션은 계속 수행되어야 한다.
트랜잭션 상태에 있는 클라이언트에서 tpcall()이나 tpacall()을 호출할 경우 flags 파라미터를 TPNOTRAN으로 설정하여 서버가 트랜잭션 참여에서 제외되도록 할 수 있다. TPNOTRAN flags로 요청받는 서버는 현재 진행 중인 트랜잭션의 결과에 영향을 줄 수 없다.
트랜잭션을 선언하는 방법은 개발자가 명시적으로 트랜잭션 관련 함수(예: tx_begin and tx_commit 등)를 직접 작성하는 Explicit 트랜잭션 방법과 서버에서 Tmax 환경 파일의 SVRGROUP 절에서 데이터베이스 관련 항목을 설정하여 서비스를 내재적으로 트랜잭션으로 처리하는 Implicit 트랜잭션 방법이 있다.
DBMS와의 연동하는 경우 확인해야 할 사항은 다음과 같다.
DBMS 벤더에서 제공하는 클라이언트 모듈의 설치를 확인한다.
DBMS 설정 항목 중 데이터베이스 - 클라이언트에 대한 세션 수 제한 등의 사항을 확인한다.
Tmax 서버 애플리케이션 작성에 필요한 개발도구 모듈이 필요하다.
XA / Non-XA 사용 여부를 확인하여 적절하게 구성한다.
서버 프로그램의 XA 모드 설정 여부는 애플리케이션 디자인 단계에서 결정되어야 한다. XA와 Non-XA는 다음과 같이 DBMS와 Tmax 간의 데이터베이스 접속 및 분산 트랜잭션 처리 방법의 차이에 따라 나뉜다.
구분 | 설명 |
---|---|
XA | Tmax 환경 파일 설정을 통해 DBMS와 접속이 이루어진다. XA의 트랜잭션 종결 또는 취소는 X/OPEN ATMI 함수를 사용하고 TMS를 통해서 종결 또는 취소 완결이 이루어진다. |
Non-XA | 사용자(개발자)의 ESQL 문을 통해서 DBMS 접속 및 트랜잭션의 종결 및 종결 취소가 처리된다. |
XA 모드의 Tmax 시스템은 별도의 트랜잭션 관리자(TMS)를 두어 트랜잭션 전체를 관리하도록 한다.
XA 모드로 운영되는 경우 모든 트랜잭션은 일단 전역 트랜잭션으로 간주되며 데이터의 무결성 확보를 위해 2PC를 사용한다. XA 모드인 경우 Tmax 환경 파일에 자원 관리자와의 접속과 접속 해제를 위한 별도의 설정이 필요하며 트랜잭션 관리는 Tmax API를 사용하여 처리하게 되고 분산 환경에서 하나 이상의 데이터베이스를 처리하는 데 필요하다. 다음은 XA 모드의 프로그램 처리 순서이다.
tpsvrinit() / tpsvrdone() 로직의 데이터베이스 접속/해제 로직은 별도로 필요하지 않다. Non-XA와 동일하게 tmboot될 때 데이터베이스와 Connection을 맺고, 별도로 TMS라는 전역 트랙잭션의 종결, 종결 취소를 담당하는 프로세스도 데이터베이스와 Connection을 맺는다. 전역 트랙잭션 시작 및 종결, 종결 취소 요청은 반드시 Tmax의 TX API를 호출하거나 혹은 Tmax 환경설정에 따라 처리한다. XA 모드를 설정하기 위해서 Tmax 환경 파일 중 SVRGROUP 절에서 DBMS와 연동할 서버 애플리케이션이 포함될 서버 그룹명을 확인하고, 그에 대한 XA 설정을 한다.
다음은 XA 모드의 SVRGROUP 절을 설정하는 예제이다.
*SVRGROUP svg1 NODENAME = tmax, DBNAME = ORACLE, OPENINFO = "ORACLE_XA+Acc=P/scott/tiger+SesTm=600", TMSNAME = svg1_tms *SERVER svr1 SVGNAME = svg1
서버 그룹 환경설정에 대한 자세한 내용은 "Tmax Administration Guide"를 참고한다.
Non-XA 모드의 Tmax 시스템은 자원 관리자에 직접 트랜잭션 명령을 내리는 것으로 분산 환경에서의 전역 트랜잭션은 사용할 수 없다. Non-XA 모드의 경우 특별히 다른 설정을 필요로 하지 않으나 애플리케이션에서 자원 관리자와 별도의 연결을 맺고 트랜잭션을 선언해야 한다.
Non-XA 모드는 네이티브 SQL과 정확하게 RDBMS에 연결된 트랜잭션 제어를 가진 서버 프로그램 방식이다. Non-XA 모드는 Tmax에서 제공하는 트랜잭션을 사용할 수 없고 로컬 트랜잭션만 가능하다. Non-XA 모드의 서버 프로그램은 간단한 Select 쿼리나 수행시간이 긴 Batch 서버 프로그램에 적합하다. Non-XA 모드에서도 트랜잭션 범위와 제어를 설정할 수 있다. 하지만 Non-XA 모드의 사용자 애플리케이션과 RDBMS(direct connection) 사이에서만 가능하다. Tmax와는 전혀 관련이 없다.
Non-XA 모드는 XA 모드와 다음과 같은 2가지 차이가 있다.
사용자 애플리케이션의 SQL을 사용하여 RDMBS와 연결하거나 연결을 끊는다.
서버 프로그램은 트랜잭션을 요청할 수 있지만 클라이언트 프로그램은 할 수 없다. Non-XA 서버 프로그램의 경우 데이터베이스와 연결하거나 해제할 때 tpsvrinit()와 tpsvrdone() 루틴을 사용하는 것을 추천한다.
다음은 Non-XA 모드의 프로그램 처리 순서이다.
tpsvrinit() 로직에 DBMS에 접속할 수 있는 로직을 작성한다.
tpsvrdone() 로직에 명시적으로 DBMS 접속을 Rollback 및 release 로직을 추가한다.
tmboot 또는 tmboot -S svrname 등을 통하여 Tmax 서버 애플리케이션을 부팅하면 DBMS와 Tmax 서버 애플리케이션 프로세스 간에 연결이 맺어진다.
서비스 로직에서는 이미 연결된 DBMS와의 연결을 통하여 ESQL을 통한 로컬 트랜잭션 전달 및 종결, 종결취소 요청을 통하여 트랜잭션 처리를 할 수 있다.
다음은 Non-XA 모드의 SVRGROUP 절을 설정하는 예제이다.
*SVRGROUP svg1 NODENAME = tmax *SERVER svr1 SVGNAME = svg1
트랜잭션 관련 함수에 대한 자세한 설명은 “9.9. 트랜잭션 관리”나 "Tmax Reference Guide"를 참고한다.
트랜잭션에 관련해서 발생할 수 있는 에러는 TX와 XA에서의 에러와 관련이 있다.
TX에 관련된 에러는 <usrinc/tx.h>에 정의되어 있고 XA에 관련된 에러는 사용하는 데이터베이스 벤더에서 제공하고 있다. Oracle의 경우 <$ORACLE_HOME/rdbms/demo/xa.h>를 참고한다.
다음은 트랙잭션 에러에 대한 설명이다.
에러 코드 | 기능 |
---|---|
TX_NOT_SUPPORTED(1) | 트랜잭션을 지원하지 않는 모드일 때 발생하는 에러이다. |
TX_OK(0) | 정상적으로 처리된 경우 발생한다. |
TX_OUTSIDE(-1) | 로컬 트랜잭션이 실행 중인 경우 발생한다. |
TX_ROLLBACK(-2) | Commit을 할 수 없는 경우 발생하는 에러로 Rollback한다. |
TX_MIXED(-3) | 일부 Commit되고 일부 Rollback된 경우이다. |
TX_HAZARD(-4) | 정상적으로 완료하지 못한 경우 발생한다. |
TX_PROTOCOL_ERROR(-5) | 트랜잭션이 비정상적으로 호출된 경우 발생한다. |
TX_ERROR(-6) | 데이터베이스 장애가 발생한 경우이다. |
TX_FAIL(-7) | 심각한 장애가 발생한 경우이다. |
TX_EINVAL(-8) | 잘못된 파라미터를 받은 경우 발생한다. |
TX_COMMITTED(-9) | 트랜잭션이 데이터베이스에 독자적으로 수행된 경우 발생한다. |
TX_NO_BEGIN(-10) | 트랜잭션은 Commit되었지만 새 트랜잭션은 시작할 수 없는 경우 발생한다. |
다음은 XA 에러에 대한 설명이다.
에러 코드 | 기능 |
---|---|
XA_OK(0) | 정상적으로 처리된 경우 발생한다. |
XAER_RMERR(-3) | OPENINFO 절에서 설정된 Resource Manager 에러가 발생한 경우이다. |
XAER_NOTA(-4) | 부여된 XID가 유효하지 않는 경우 발생한다. |
XAER_INVAL(-5) | 잘못된 파라미터를 받은 경우 발생한다. |
XAER_PROTO(-6) | 부적절한 단계에서 호출된 경우 발생한다. |
XAER_RMFAIL(-7) | 데이터베이스와 연결에 실패한 경우 발생한다. |
XAER_DUPID(-8) | 이미 부여된 XID를 사용한 경우 발생한다. |
XAER_OUTSIDE(-9) | 트랜잭션 모드에서 벗어난 경우 발생한다. |