내용 목차
본 장에서는 Tibero와 Tuxedo 연동 예제 프로그램의 전체 소스 코드와 각종 스크립트를 설명한다.
다음은 시스템 환경변수 설정 파일이다.
# 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
다음은 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
다음은 필드 테이블 파일이다.
#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 -
다음은 서버 프로그램 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); }
다음은 서버 프로그램 빌드 스크립트이다.
#### 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 클라이언트 프로그램 파일이다.
#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 클라이언트 프로그램 파일이다.
#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(); } ~
다음은 클라이언트 프로그램 빌드 스크립트이다.
buildclient -o insert -v -f insert.c buildclient -o select -v -f select.c
다음은 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) ); ~
다음은 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