본 장에서는 실제 XA 라이브러리와 XA 게이트웨이를 사용하기 위한 기본적인 API 사용법과 환경 설정 방법 등을 설명한다.
Tmax의 서비스를 요청하기 위한 API로 XA 라이브러리는 동기형 call과 비동기형 call을 제공한다.
동기형 call로서는 tpcall을 제공한다.
tpcall은 tmax의 클라이언트 라이브러리 및 서버 라이브러리에서 사용하는 API로, 동일한 구조로 XA 라이브러리에서 사용할 수 있다.
서버와 클라이언트의 동기형 서비스 요청 송수신 함수로 동기형 통신으로 svc로 명명된 서비스에게 서비스 요청을 송신하고 이에 대한 응답을 수신한다. tpacall() 호출 후 연속적으로 tpgetrply()를 호출하는 것과 동일하게 처리된다.
tx_begin 호출 이후 tx_time이 지난 이후에 tpacall은 TPNOTRAN | TPNOREPLY를 flag에 설정한 호출만 성공하며 나머지는 모두 TPETIME 에러를 발생시킨다.
프로토타입
# include <atmi.h>
int tpcall (char *svc, char *idata, long ilen, char **odata, long *olen,
long flags)
파라미터
| 파라미터 | 설명 |
|---|---|
| svc | 호출되는 서비스명으로 Tmax 응용 서버 프로그램에서 제공되고 있는 것이어야 한다. |
| idata | 서비스 요청의 데이터에 대한 포인터이다. 반드시 이전에 tpalloc()에 의해 할당된 버퍼이어야 한다. idata의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유형이어야 한다. |
| ilen | 송신할 데이터의 길이이다.
|
| *odata | *odata는 수신될 응답 버퍼에 대한 포인터로 버퍼는 *olen으로 반환된 길이 만큼의 응답이 수신된다. *odata는 반드시 이전에 tpalloc()에 의해 할당된 버퍼이어야 한다. 동일한 버퍼가 송신과 수신 역할을 모두 한다면, *odata는 idata의 주소로 설정되어야 한다. 응답 버퍼의 크기 변경 여부를 결정하기 위해서 tpcall()의 완료 전에 *odata로 할당된 응답 버퍼의 크기와 수신된 *olen을 비교한다. 수신된 *olen이 더 크다면 할당된 응답 버퍼의 크기가 증가되며, 그렇지 않으면 크기는 변경되지 않는다. idata와 *odata로 동일한 버퍼가 사용되어 tpcall()이 호출된 경우 *odata가 변경되었다면 idata가 가리키는 주소는 더 이상 유효하지 않다. *odata는 수신 데이터가 커서 변경될 수도 있고, 이 외에 다른 이유에 의해서도 변경될 수 있다. *olen이 0으로 반환되었다면, 어떤 데이터도 수신되지 않고 *odata와 *odata가 가리키는 버퍼 모두 아무런 변화가 없다. *odata나 olen이 NULL이 되는 것은 에러이다. |
| *olen | *odata에 반환될 응답에 대한 길이이다. |
| flags | 호출할 때 사용되는 옵션으로 어떤 방식으로 통신할 것인지를 지정한다. flags로 사용 가능한 값은 다음과 같다.
|
반환값
| 반환값 | 설명 |
|---|---|
| 1 | 함수 호출에 성공한 경우이다. |
| -1 | 함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다. |
오류
tpcall()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
| 에러 코드 | 설명 |
|---|---|
| [TPEINVAL] | 파라미터가 유효하지 않거나 flags가 유효하지 않다. 예를 들어 svc가 NULL이거나 data가 tpalloc()으로 할당되지 않은 버퍼를 가리킨다. |
| [TPENOENT] | svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다. |
| [TPEITYPE] | data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. |
| [TPEOTYPE] | 수신된 응답 버퍼의 유형이나 하위 유형이 호출자가 알지 못하는 유형이다. flags가 TPNOCHANGE로 설정되었는데 *odata가 가리키는 버퍼의 유형 및 하위 유형이 수신된 응답 버퍼의 유형 및 하위 유형과 맞지 않은 경우 *odata의 내용과 *olen은 모두 변경되지 않는다. 호출자가 트랜잭션 모드에서 서비스를 요청하였다면, 그 트랜잭션은 응답이 무시되었기 때문에 rollback된다. |
| [TPETRAN] | 트랜잭션 서비스를 호출할 때 데이터 베이스에 문제가 발생하여 xa_start가 실패하였다. |
[TPETIME] | 타임아웃이 발생한 경우로 함수 호출자가 트랜잭션 모드에 있다면 트랜잭션 타임아웃이 발생하였고 그 트랜잭션은 rollback된다. 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK 어느 것도 지정되지 않았다면, 블록 타임아웃이 발생한다. 이 두 경우에 *odata의 내용과 *olen은 변경되지 않는다. 트랜잭션 타임아웃이 발생하였다면 새로운 서비스 요청을 송신한다거나 응답을 대기하는 일은 트랜잭션이 rollback될 때까지 [TPETIME] 에러로 실패하게 된다. |
[TPESVCFAIL] | 서비스 요청에 대한 응답을 송신하는 서비스 루틴이 애플리케이션에서 에러가 발생하여 TPFAIL로 tpreturn()을 호출하였다. 서비스 응답이 수신되었다면 그 내용들은 *odata가 가리키는 버퍼를 통하여 사용될 수 있다. 트랜잭션 타임아웃이 발생해서 트랜잭션이 rollback되기 전에 다른 통신들이 시도될 수 있다. 그러한 통신들은 정상적으로 처리될 수도 있고, 또는 실패할 수도 있다. 통신이 정상적으로 수행되기 위해서는 TPNOTRAN이 설정되어야 한다. 호출자의 트랜잭션 모드에서 수행된 작업들은 트랜잭션을 완료할 때에 모두 rollback된다. |
[TPESVCERR] | 서비스 루틴 수행 중이나 tpreturn()(예를 들어 잘못된 파라미터가 전달된 경우) 수행 중에 에러가 발생하였다. 에러가 발생하면 어떠한 응답 데이터도 반환되지 않고 *odata의 내용 또는 *olen 모두 변경되지 않는다. tpalloc로 생성되지 않은 버퍼를 사용하였거나 할당된 버퍼의 Tmax 헤더가 잘못된 포인터(memcpy 등)의 영향을 받았거나, tpacall이나 tpconnect의 cd로 반환하였을 경우 Recv 모드에서 서비스가 유효하지 않은 대화형 내용일 경우에 발생한다. 단, tpreturn을 시도하면 클라이언트는 TPESVCERR를 받는다. 클라이언트가 강제로 대화를 해제하여 서비스 프로그램이 TPEV_DISCOMN을 받는 것과 같은 TPEV_DISCOMN 이벤트가 발생하였을 경우 클라이언트는 서비스의 tpreturn에 TPESVCERR tperrno를 전송받는다. 함수 호출자가 트랜잭션 모드에 있을 경우 트랜잭션 타임아웃이 발생하기 전까지는 트랜잭션이 rollback되기 전에 다른 통신들이 시도될 수 있다. 그러한 통신들은 정상적으로 처리될 수도 있고, 또는 실패할 수도 있다. 이들이 제대로 수행되기 위해서는 TPNOTRAN이 설정되어야 한다. 호출자의 트랜잭션 모드에서 수행된 작업들은 트랜잭션이 완료되면 모두 rollback된다. Tmax 환경 파일에 서비스별로 SVCTIMEOUT을 설정할 수 있는데 서비스의 수행시간이 이 시간을 초과하게 되면 서비스는 수행을 멈추고 TPESVCERR를 반환한다. SVCTIMEOUT이 발생하면 tpsvctimeout()을 불러주는데 이 함수 내에서 버퍼 해제, 로깅 작업 등 업무별로 적당한 작업을 할 수 있다. |
| [TPEBLOCK] | TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다. |
| [TPGOTSIG] | TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다. |
| [TPEPROTO] | tpcall()이 부적절한 상황에서 호출되었다. |
| [TPESYSTEM] | Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다. |
| [TPEOS] | 운영 시스템에 에러가 발생하였다. |
예제
#include <stdio.h>
#include <usrinc/atmi.h>
void main(int argc, char *argv[])
{
int ret;
char *sndbuf, *rcvbuf;
long sndlen, rcvlen;
ret=tpstart((TPSTART_T *)NULL);
if (ret==-1) { error processing }
sndbuf = (char *)tpalloc(“CARRAY”, NULL, 20);
if (sndbuf==NULL) {error processing };
rcvbuf = (char *)tpalloc(“CARRAY”, NULL, 20);
if (rcvbuf==NULL) {error processing };
data process....
sndbuf=strlen(sndbuf);
ret=tpcall(”SERVICE”, sndbuf, sndlen, &rcvbuf, &rcvlen, TPNOCHANGE);
if (ret==-1) { error processing }
data process....
tpfree((char *)sndbuf);
tpfree((char *)rcvbuf);
tpend();
}
관련 함수
tpalloc(), tpacall(), tpgetrply(), tpreturn()
비동기형 call로 tpacll과 응답을 받기위한 tpgetrply를 제공한다. tpacall, tpgetrply는 tmax의 클라이언트 라이브러리 및 서버 라이브러리에서 사용하는 API로, 동일한 구조로 XA 라이브러리에서 사용할 수 있다.
서버와 클라이언트에서 비동기 서비스 요청을 송신하는 함수로 svc로 명명된 서비스에게 서비스 요청 메시지를 송신한다. 비동기 통신으로 메시지를 송신한 후에 결과를 받을 때까지 기다리지 않고 바로 반환된다. 결과는 tpgetrply()를 이용하여 응답을 받을 수도 있고, 또는 tpcancel()를 이용하여 응답을 취소할 수 있다.
tx_begin 호출 이후 tx_time이 지난 이후에 tpacall은 TPNOTRAN | TPNOREPLY를 flag에 설정한 호출만 성공하며 나머지는 모두 TPETIME 에러를 발생시킨다.
tpacall이 성공한 경우 반환값 범위의 제한은 int 값 범위 중 양의 정수 부분인 1부터 2147438647이다.
프로토타입
# include <atmi.h> int tpacall (char *svc, char *data, long len, long flags)
파라미터
| 파라미터 | 설명 |
|---|---|
| svc | 호출되는 서비스명으로 Tmax 응용 서버 프로그램에서 제공되는 것이어야 한다. |
| data | NULL 값이 아닌 경우 반드시 tpalloc()으로 할당된 버퍼에 대한 포인터이어야 한다. |
| len | 송신되는 데이터 길이이다.
|
| flags | 호출할 때 사용되는 옵션으로 호출 모드를 결정한다. flags로 사용 가능한 값은 다음과 같다.
|
반환값
| 반환값 | 설명 |
|---|---|
| 구별자(descriptor) | 함수 호출에 성공한 경우이다. 반환된 구별자는 송신된 서비스 요청에 대한 응답을 수신하는 데 사용된다. |
| -1 | 함수 호출이 실패한 경우이다. tperrno에 에러 코드가 설정된다. |
오류
tpacall()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
| 에러 코드 | 설명 |
|---|---|
| [TPEINVAL] | 파라미터가 유효하지 않은 경우 발생한다. 예를 들어 svc가 NULL이거나 data가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나 또는 flags가 유효하지 않은 경우에 발생한다. |
| [TPENOENT] | svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다. |
| [TPEITYPE] | data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인 경우 사용된 구조체가 SDLFILE 파일에 선언되어 있지 않은 경우 발생한다. |
| [TPELIMIT] | 처리되지 않은 비동기성 서비스 요청 수가 최대 한계에 도달했기 때문에 호출자의 서비스 요청이 송신되지 않은 경우 발생한다. |
| [TPETIME] | 타임아웃이 발생한 경우로 함수 호출자가 트랜잭션 모드인 경우 트랜잭션 타임아웃이 발생한 것이며 트랜잭션은 rollback된다. 함수 호출자가 트랜잭션 모드가 아닌 경우 TPNOTIME이나 TPNOBLOCK이 모두 설정되지 않은 상황에서 블록 타임아웃이 발생한다. 트랜잭션 타임아웃이 발생하는 경우 트랜잭션이 rollback될 때까지 새로운 서비스 요청을 송신한다거나 아직 수신되지 않은 응답을 기다리는 일은 모두 [TPETIME] 에러로 실패 처리된다. |
| [TPEBLOCK] | TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다. |
| [TPGOTSIG] | TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다. |
| [TPEPROTO] | 트랜잭션 모드에서의 TPNOREPLY 서비스 호출할 때 TPNOTRAN flags를 설정하지 않는 경우 등 부적절한 상황에서 발생한다. |
| [TPESYSTEM] | Tmax 시스템에 에러가 발생하였다. |
| [TPEOS] | 운영 시스템에 에러가 발생하였다. |
예제
#include <stdio.h>
#include <usrinc/atmi.h>
void main(int argc, char *argv[])
{
char *buf;
int ret,cd;
long len;
ret=tpstart((TPSTART_T *)NULL);
if (ret<0) { error processing }
buf = (char *)tpalloc(“CARRAY”, NULL, 20);
if (buf==NULL) {error processing }
data process....
cd = tpacall(“SERVICE”, sndbuf, 20, TPNOTIME);
if (cd<0) {error processing }
data process…
ret=tpgetrply(&cd, (char **)&buf, &len, TPNOTIME);
if (ret<0) { error processing }
data process....
tpfree((char *)buf);
tpend();
}
관련함수
tpalloc(), tpcall(), tpcancel(), tpgetrply()
서버와 클라이언트에서 비동기적으로 요청한 서비스에 대한 응답을 수신하는 함수로 tpacall()로 요청한 서비스에 대한 응답을 수신한다.
프로토타입
# include <atmi.h> int tpgetrply(int *cd, char **data, long *len, long flags)
파라미터
| 파라미터 | 설명 |
|---|---|
| cd | tpacall()에 의해 반환된 호출 구별자를 가리킨다. 보통 cd와 일치하는 응답이 수신되거나 또는 타임아웃이 발생할 때까지 기다린다. 일반적으로 cd는 응답이 수신된 후에는 더 이상 유효하지 않다. |
| *data | 반드시 이전에 tpalloc()에 의해 할당된 버퍼에 대한 포인터이어야 한다. |
| len | tpgetrply()가 성공적으로 수신한 데이터의 길이로 필요한 경우 응답 내용이 지정된 버퍼에 수신될 수 있도록 버퍼 크기를 증가시킨다. *data는 수신 데이터가 커서 변경될 수도 있고, 이 외에 다른 이유에 의해서도 변경될 수 있다. len이 호출 전 버퍼의 총 크기보다 크다면, len이 그 버퍼의 새로운 크기가 된다. len이 0으로 반환되는 경우 어떤 응답도 수신되지 않고 *data와 len이 지시하는 버퍼 모두 아무런 변화가 없다. *data나 len이 NULL이 되는 것은 에러이다. |
| flags | flags로 사용 가능한 값은 다음과 같다.
|
반환값
| 반환값 | 설명 |
|---|---|
| 1 | 함수 호출에 성공한 경우이다. tpreturn()으로 전달되는 tpurcode 전역변수는 tpgetrply()가 성공적으로 반환되었거나 tperrno가 [TPESVCFAIL]인 경우 애플리케이션에서 정의한 값을 갖게 된다. |
| -1 | 함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다. |
오류
tpgetrply()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
| 에러 코드 | 설명 |
|---|---|
| [TPEINVAL] | 파라미터가 유효하지 않다. 예를 들어 cd나 data, *data, len 등이 NULL이거나 또는 flags가 유효하지 않은 경우에 발생한다. cd가 NULL이 아니면 에러 발생 후에도 cd는 유효하며, 그에 대한 응답을 계속 기다린다. |
| [TPEBADDESC] | cd가 유효하지 않은 구별자이다. |
| [TPEOTYPE] | 수신된 응답의 유형 또는 하위 유형이 호출자가 알지 못하는 유형이다. flags가 TPNOCHANGE로 설정되었는데, *data의 유형 및 하위 유형이 서비스가 송신한 응답의 것과 맞지 않는 경우로 *data의 내용과 *len은 모두 변경되지 않는다. 응답이 호출자의 트랜잭션 모드에서 수신되었다면, 그 트랜잭션은 응답이 무시되었기 때문에 rollback된다. |
| [TPETIME] | 타임아웃이 발생한 경우로 함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생하였고 그 트랜잭션은 rollback된다. 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK 어느 것도 지정되지 않았다면, 블록 타임아웃이 발생하였다. 이 두 경우에, *data의 내용과 *len은 변경되지 않는다. 트랜잭션 타임아웃이 발생했다면, 새로운 서비스 요청을 송신한다거나 응답을 기다리는 일은 트랜잭션이 rollback될 때까지 [TPETIME] 에러로 실패하게 된다. |
| [TPESVCFAIL] | 서비스 요청에 대한 응답을 송신하는 서비스 루틴이 애플리케이션에 에러가 발생하여 TPFAIL로 tpreturn()을 호출하였다. 서비스 응답이 수신되었다면, 그 내용들은 *data가 가리키는 버퍼를 통해 사용될 수 있다. 함수 호출자가 트랜잭션 모드에 있다면, 그 트랜잭션은 rollback된다. 트랜잭션 타임아웃이 발생하기 전까지는 트랜잭션이 rollback되기 전에 다른 통신들이 시도될 수 있다. 그러한 통신들은 정상적으로 처리될 수도 있고, 또는 실패할 수도 있다. 이들이 제대로 수행되기 위해서는 TPNOTRAN이 설정되어야 한다. 호출자의 트랜잭션 모드에서 수행된 작업들은 트랜잭션이 완료되면 모두 rollback된다. |
| [TPEBLOCK] | TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하는 경우로 구별자(cd)는 유효하다. |
| [TPGOTSIG] | TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다. |
| [TPEPROTO] | tpgetrply()이 부적절한 상황에서 호출되었다. |
| [TPETRAN] | 트랜잭션 서비스를 호출할 때 데이터베이스에 문제가 발생하여 xa_start가 실패하였다. |
| [TPESYSTEM] | Tmax 시스템에 에러가 발생하였다. |
| [TPEOS] | 운영 시스템에 에러가 발생하였다. |
예제
#include <stdio.h>
#include <usrinc/atmi.h>
void main(int argc, char *argv[])
{
int ret;
long len;
char *buf;
ret=tpstart((TPSTART_T *)NULL);
if (ret==-1) { error processing }
buf = (char *)tpalloc(“STRING”, NULL, 0);
if (buf==NULL) { error processing }
data process …
cd = tpacall(“SERVICE”, buf, 0, TPNOFLAGS);
if (cd==-1) { error procesing }
data process....
ret=tpgetrply(&cd, &buf, &len, TPNOTIME);
if (ret==-1) { error processing }
data process....
tpfree(buf);
tpend();
}
관련함수
tpacall(), tpalloc(), tpreturn()