> For the complete documentation index, see [llms.txt](https://docs.tibero.com/tibero-manuals/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tibero.com/tibero-manuals/7.2.6.manuals/development-guide/appendix-b.example-of-integrating-with-tuxedo.md).

# 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=tibero32.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"
                  
tiberohost        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
```

## tibero32.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
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tibero.com/tibero-manuals/7.2.6.manuals/development-guide/appendix-b.example-of-integrating-with-tuxedo.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
