Appendix B. Tibero와 Tuxedo 연동 예제
본 장에서는 Tibero와 Tuxedo 연동 예제 프로그램의 전체 소스 코드와 각종 스크립트를 설명합니다.
tb_tux.env
다음은 시스템 환경변수 설정 파일입니다.
# for tibero
export TB_HOME=/path/to/tibero
export TB_SID=tibero
export PATH=$TB_HOME/bin:$TB_HOME/client/bin:$TB_HOME/scripts:$PATH
export LD_LIBRARY_PATH=$TB_HOME/client/lib:$TB_HOME/lib:$LD_LIBRARY_PATH
export LIBPATH=$TB_HOME/client/lib:$TB_HOME/lib:$LIBPATH
# for tuxedo
export TUXDIR=/path/to/tuxedo
export JAVA_HOME=$TUXDIR/jre
export JVMLIBS=$JAVA_HOME/lib/amd64/server:$JAVA_HOME/jre/bin
export PATH=$TUXDIR/bin:$JAVA_HOME/bin:$PATH
export COBCPY=:$TUXDIR/cobinclude; export COBCPY
export COBOPT="-C ANS85 -C ALIGN=8 -C NOIBMCOMP -C TRUNC=ANSI -C OSEXT=cbl"
export SHLIB_PATH=$TUXDIR/lib:$JVMLIBS:$SHLIB_PATH
export LIBPATH=$TUXDIR/lib:$JVMLIBS:$LIBPATH
export LD_LIBRARY_PATH=$TUXDIR/lib:$JVMLIBS:$LD_LIBRARY_PATH
export WEBJAVADIR=$TUXDIR/udataobj/webgui/java
export TUXCONFIG=/path/to/tuxedo/tuxconf
export FLDTBLDIR32=/path/to/tuxedo
export FIELDTBLS32=tmax32.fld
export TLOGDEVICE=/path/to/tuxedo/TLOG
export ULOGPFX=/path/to/tuxedo/ULOG
tb_tux.conf.m
다음은 Tuxedo 환경설정 파일입니다.
*RESOURCES
IPCKEY 68300
DOMAINID tbrdomain
MASTER tbrtest
MAXACCESSERS 10
MAXSERVERS 5
MAXSERVICES 20
MODEL SHM
LDBAL N
*MACHINES
DEFAULT:
TUXDIR="/data1/apmqam/oracle/tuxedo/tuxedo10gR3"
APPDIR="/data1/apmqam/tibero_tuxedo_test"
TUXCONFIG="/data1/apmqam/tibero_tuxedo_test/tuxconf"
TLOGDEVICE="/data1/apmqam/tibero_tuxedo_test/TLOG"
tmaxi4 LMID=tbrtest
*GROUPS
TBXA LMID=tbrtest GRPNO=1
TMSNAME=tms_tibero
OPENINFO="TIBERO_XA:TIBERO_XA:user=sys,pwd=tibero,
sestm=60,db=tibero"
*SERVERS
DEFAULT:
CLOPT="-A -r"
trans_fml32 SRVGRP=TBXA SRVID=1
*SERVICES
SELECT_FML32
INSERT_FML32
tmax32.fld
다음은 필드 테이블 파일입니다.
#name number type flag comment
OUTPUT 302 string 0 -
EMPNO 901 long 0 -
ENAME 902 string 0 -
JOB 903 string 0 -
MGR 904 long 0 -
SAL 905 float 0 -
COMM 906 float 0 -
DEPTNO 907 long 0 -
trans_fml32.tbc
다음은 서버 프로그램 tbESQL/C 파일입니다.
#include <stdio.h>
#include <atmi.h>
#include <userlog.h>
#include <Uunix.h>
#include <fml32.h>
#include "fml32.fld.h"
#include <tx.h>
#include "sqlca.h"
EXEC SQL include SQLCA.H;
EXEC SQL begin declare section;
int h_empno;
char h_ename[10];
char h_job[10];
EXEC SQL end declare section;
void INSERT_FML32(rqst)
TPSVCINFO *rqst;
{
FBFR32 *sndbuf;
char msgbuf[256];
FLDLEN32 flen;
XID *xid;
TXINFO info;
char xidstring[1000];
char str[100];
int i;
sndbuf = (FBFR32 *)rqst->data;
tx_info(&info);
xid = &(info.xid);
memset( xidstring, 0x00, 1000);
for( i = 0 ; i < xid->gtrid_length+xid->bqual_length ; i++ )
{
sprintf(xidstring+strlen(xidstring),"%0x\0",xid->data[i]);
}
Fprint32(sndbuf);
memset( &h_empno, 0x00, sizeof ( h_empno ) );
memset( h_ename, 0x00, sizeof ( h_ename ) );
memset( h_job, 0x00, sizeof ( h_job ) );
Fget32(sndbuf, EMPNO, 0, (char *)&h_empno, &flen);
Fget32(sndbuf, ENAME, 0, (char *)h_ename, &flen);
Fget32(sndbuf, JOB, 0, (char *)h_job, &flen);
printf("SVR: EMPNO %d ENAME %s JOB %s\n", h_empno, h_ename, h_job);
printf("SVR: INSERT_FML32 XID:%d.%d. %0x.%s - %s\n\n",
xid->gtrid_length, xid->bqual_length,
xid->formatID, xidstring, h_ename);
EXEC SQL INSERT
INTO emp( empno, ename, job )
VALUES ( :h_empno, :h_ename, :h_job );
if ( sqlca.sqlcode != 0 ){
sprintf(msgbuf, "insert fail: sqlcode = %d(%s)\n",
sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
Fchg32(sndbuf, OUTPUT, 0, msgbuf, 0);
tpreturn(TPFAIL, -1, (char *)sndbuf, 0, 0);
}
strcpy(msgbuf, "insert success!" );
Fchg32(sndbuf, OUTPUT, 0, msgbuf, 0);
tpreturn(TPSUCCESS, 0, rqst->data, strlen(rqst->data), 0);
}
void SELECT_FML32(rqst)
TPSVCINFO *rqst;
{
FBFR32 *sndbuf;
char msgbuf[256];
FLDLEN32 flen;
sndbuf = (FBFR32 *)rqst->data;
Fprint32(sndbuf);
Fget32(sndbuf, EMPNO, 0, (char *)&h_empno, &flen);
EXEC SQL SELECT NVL(ename,' '), NVL(job,' ')
INTO :h_ename,:h_job
FROM emp
WHERE empno = :h_empno;
if ( sqlca.sqlcode != 0 ){
sprintf(msgbuf, "select failed sqlcode = %d(%s)\n",
sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
Fchg32(sndbuf, OUTPUT, 0, msgbuf, 0);
tpreturn(TPFAIL, -1, (char *)sndbuf, 0, 0);
}
printf("#### %d \n", h_empno);
Fchg32(sndbuf, ENAME, 0,(char *)h_ename, 0);
Fchg32(sndbuf, JOB, 0, (char *)h_job, 0);
Fchg32(sndbuf, EMPNO, 0, (char *)&h_empno, 0);
strcpy(msgbuf, "select success!" );
Fchg32(sndbuf, OUTPUT, 0, msgbuf, 0);
Fprint32(sndbuf);
tpreturn(TPSUCCESS, 0,(char *)sndbuf, sizeof(sndbuf), 0);
}
builds.sh
다음은 서버 프로그램 빌드 스크립트입니다.
#### transaction server precompile ####
PRECOMP=$TB_HOME/client/bin/tbpc
PRECOMPFLAGS="UNSAFE_NULL=YES"
LIB=$TB_HOME/client/lib
INC=$TB_HOME/client/include
CFLAGS="-ltbcli -ltbxa -lm -lrt -lpthread -ltbertl -g "
CC=gcc
rm -f trans_fml32.c
$PRECOMP INCLUDE=$TUXDIR/include UNSAFE_NULL=YES INCLUDE=$INC
$PRECOMPFLAGS ONAME=trans_fml32.c trans_fml32.tbc
#### transaction server build ####
buildserver -o trans_fml32 -v -f trans_fml32.c -s INSERT_FML32,SELECT_FML32 -r
TIBERO_XA
insert.c
다음은 INSERT 클라이언트 프로그램 파일입니다.
#include <stdio.h>
#include <atmi.h>
#include <fml32.h>
#include <string.h>
#include "fml32.fld.h"
struct temp_str{
int empno;
char ename[11];
char job[10];
};
typedef struct temp_str *str;
main(argc, argv)
char *argv[];
{
FBFR32 *sendbuf;
FBFR32 *recvbuf;
long recvlen = 0;
int ret;
str tmpbuf;
char msgbuf[30];
FLDLEN32 flen;
tmpbuf = malloc(sizeof(struct temp_str));
if (tpinit((TPINIT *) NULL) == -1)
{ fprintf(stderr, "Tpinit
failed\n"); exit(1);
}
if((sendbuf = (FBFR32 *) tpalloc("FML32", NULL, 0)) == NULL)
{ fprintf(stderr,"Error allocating send buffer\n");
tpterm();
exit(1);
}
if((recvbuf = (FBFR32 *) tpalloc("FML32", NULL, 0)) == NULL)
{ fprintf(stderr,"Error allocating receive buffer\n");
tpfree((char *)sendbuf);
tpterm();
exit(1);
}
tmpbuf = malloc(sizeof(struct temp_str));
printf("\n******************************************\n");
printf( "| Employee Number : " ); scanf ( "%d", &tmpbuf->empno );
printf( "| Employee Name : " ); scanf ( "%s", tmpbuf->ename );
printf( "| Employee Job : " ); scanf ( "%s", tmpbuf->job );
printf("******************************************\n\n");
tpbegin(10, 0);
Fchg32(sendbuf,EMPNO,0,(char *)&tmpbuf->empno,0);
Fchg32(sendbuf,ENAME,0,(char *)tmpbuf->ename,0);
Fchg32(sendbuf,JOB,0,(char *)tmpbuf->job,0);
ret = tpcall("INSERT_FML32", (char *)sendbuf, 0, (char **)&recvbuf,
&recvlen, (long)0);
if(ret == -1) {
fprintf(stderr, "tperrno = %d (%s) \n", tperrno, tpstrerror(tperrno));
tpfree((char *)sendbuf);
tpfree((char *)recvbuf);
tpterm();
exit(1);
}
flen = sizeof( msgbuf );
Fget32(recvbuf, OUTPUT, 0, (char *)msgbuf, &flen);
printf("%s\n", msgbuf);
tpcommit(0);
free(tmpbuf);
tpfree((char *)sendbuf);
tpterm();
}
select.c
다음은 SELECT 클라이언트 프로그램 파일입니다.
#include <stdio.h>
#include <atmi.h>
#include <fml32.h>
#include <string.h>
#include "fml32.fld.h"
main(argc, argv)
char *argv[];
{
FBFR32 *sendbuf;
FBFR32 *recvbuf;
long recvlen;
int ret;
int empno;
FLDLEN32 flen;
int h_empno;
char h_ename[10];
char h_job[10];
char msgbuf[256];
if (tpinit((TPINIT *) NULL) == -1)
{ fprintf(stderr, "Tpinit
failed\n"); exit(1);
}
if((sendbuf = (FBFR32 *) tpalloc("FML32", NULL, 0)) == NULL)
{ fprintf(stderr,"Error allocating send buffer\n");
tpterm();
exit(1);
}
if((recvbuf = (FBFR32 *) tpalloc("FML32", NULL, 0)) == NULL)
{ fprintf(stderr,"Error allocating receive buffer\n");
tpfree((char *)sendbuf);
tpterm();
exit(1);
}
printf("\n******************************************\n");
printf( "| Employee Number : " ); scanf ( "%d", &empno );
printf("******************************************\n\n");
Fchg32(sendbuf,EMPNO,0,(char *)&empno,0);
ret = tpcall("SELECT_FML32", (char *)sendbuf, 0, (char **)&recvbuf,
&recvlen, (long)0);
if(ret == -1) {
fprintf(stderr, "tperrno = %d (%s)\n", tperrno, tpstrerror(tperrno));
flen = sizeof( msgbuf );
Fget32(recvbuf, OUTPUT, 0, (char *)msgbuf, &flen);
printf("error msg: %s\n", msgbuf);
tpfree((char *)sendbuf);
tpfree((char *)recvbuf);
tpterm();
exit(1);
}
flen = sizeof(msgbuf);
Fget32(recvbuf, OUTPUT, 0, (char *)msgbuf, &flen);
printf("%s\n", msgbuf);
flen = sizeof(&h_empno);
Fget32(recvbuf, EMPNO, 0, (char *)&h_empno, &flen);
printf("EMPNO; %d \n", h_empno);
flen = sizeof(h_ename);
Fget32(recvbuf, ENAME, 0, (char *)h_ename, &flen);
printf("ENAME: %s \n", h_ename);
flen = sizeof(h_job);
Fget32(recvbuf, JOB, 0, (char *)h_job, &flen);
printf("JOB: %s \n", h_job);
tpfree((char *)recvbuf);
tpfree((char *)sendbuf);
tpterm();
buildc.sh
다음은 클라이언트 프로그램 빌드 스크립트입니다.
buildclient -o insert -v -f insert.c
buildclient -o select -v -f select.c
create_table.sql
다음은 SELECT 클라이언트 프로그램 파일입니다.
drop table emp;
CREATE TABLE emp (
empno NUMBER,
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2)
);
~
run.sh
다음은 Tuxedo 시스템 기동 스크립트입니다.
#!/bin/sh
tmshutdown -y
rm ULOG* > /dev/null 2>&1
rm xa* > /dev/null 2>&1
tmloadcf -y tb_tux.conf.m
rm /data1/apmqam/tibero_tuxedo_test/TLOG* > /dev/null 2>&1
rm /data1/apmqam/tibero_tuxedo_test/ULOG* > /dev/null 2>&1
tmadmin -c << EOF
crdl -z /data1/apmqam/tibero_tuxedo_test/TLOG -b 1000
q
EOF
tmboot -y
Last updated