> 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.5.manuals/tibero-development-guide/appendix-b.example-of-integrating-with-tuxedo.md).

# Appendix B. 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
```


---

# 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.5.manuals/tibero-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.
