Table of Contents
This chapter describes examples of MultipleRM programs, environment configuration, and makefile for compilation in TCS.
In TCS, Oracle and Tibero can be used through the server library. This section describes examples of MultipleRM programs, environment configuration, and makefile for compilation.
The following shows sample TCS programs that use both Oracle and Tibero. The program examples can be used by writing a server program with Embedded SQL and pre-compiling it with the pre-compiler provided by each database vendor.
The following is program source code that executes a service.
#include <stdio.h> #include <usrinc/atmi.h> extern int oracle_call(TPSVCINFO *msg); extern int tibero_call(TPSVCINFO *msg); MDB_SVC1(TPSVCINFO *msg) { int ret; int fail = 0; ret = oracle_call(msg); if (ret < 0) { fail = 1; } ret = tibero_call(msg); if (ret < 0) { fail = 1; } if ( fail ) { tpreturn(TPFAIL,0,(char *)msg->data, msg->len,0); } tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0); }
The following program uses a function to call Oracle.
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tx.h> EXEC SQL include sqlca.h; EXEC SQL begin declare section; char h_addr[100]; EXEC SQL end declare section; int oracle_call(TPSVCINFO *msg) { int i; strcpy(h_addr, msg->data); EXEC SQL INSERT INTO account( account_id, address, phone ) VALUES ( tmax_seq.nextval,:h_addr, '007-1234' ); if ( sqlca.sqlcode != 0 ){ printf( "insert failed sqlcode = %d\n",sqlca.sqlcode ); tpreturn( TPFAIL, -1, NULL, 0, 0 ); } printf("ORACLE insert Success\n"); return 0; }
The following program uses a function to call Tibero.
#include <stdio.h> #include <string.h> #include <usrinc/atmi.h> EXEC SQL include sqlca.h; EXEC SQL begin declare section; char h_addr[100]; EXEC SQL end declare section; int tibero_call(TPSVCINFO *msg) { strcpy(h_addr, msg->data); EXEC SQL INSERT INTO account( account_id, address, phone ) VALUES ( tmax_seq.nextval,:h_addr, '007-1234' ); if ( sqlca.sqlcode != 0 ){ printf( "tibero insert failed sqlcode = %d\n",sqlca.sqlcode ); tpreturn( TPFAIL, -1, NULL, 0, 0 ); } printf("TIBERO insert Success\n"); return 0; }
The following shows the environment configuration and compilation of MultipleRM that uses both Oracle and Tibero.
The following is a MultipleRM server configuration example.
*DOMAIN domain SHMKEY = 81522, MAXUSER = 10000, MINCLH = 1, MAXCLH = 1, TPORTNO = 11500, BLOCKTIME = 30, MAXSACALL = 1024, MAXCACALL = 1024, MAXMTMAX = 3, MAXSTMAX = 10 *NODE node1 TMAXDIR = "/home/tmax", APPDIR = "/home/tmax/appbin", PATHDIR = "/home/tmax/path", TLOGDIR = "/home/tmax/log/tlog", ULOGDIR = "/home/tmax/log/ulog", SLOGDIR = "/home/tmax/log/slog" *SVRGROUP svg_s1 NODENAME = node1, DBNAME = ORACLE, OPENINFO ="Oracle_Xa+SqlNet=TMAX+Acc=P/scott/tiger+SesTm=60", TMSNAME = tms_ora, SVGTYPE = STMAX svg_s2 NODENAME = node1, DBNAME = TIBERO, OPENINFO ="TIBERO_XA:user=scott,pwd=tiger, sestm=60,db=TMAX", TMSNAME = tms_tbr, SVGTYPE = STMAX
-lnodb must be included in the LIBS (Tmax library) item of the makefile.
The following is a makefile that compiles a MultipleRM server program in 32bit Linux.
# Oracle Env
ORALIBDIR = /home/OraHome1/lib/
ORALIB = -lclntsh `cat /home/OraHome1/lib/ldflags` `cat /home/OraHome1/lib/sysliblist` -ldl -lm
# Tibero Env
TBRLIB = -ltbxa -ltbertl
TBRLIBDIR = $(TB_HOME)/client/lib
TBRINCDIR = $(TB_HOME)/client/include
$ Server build
TARGET = $(COMP_TARGET)
APOBJS = $(TARGET).o
AP_ORA_OBJS = $(TARGET)_ora.o
AP_TBR_OBJS = $(TARGET)_tbr.o
NSDLOBJ = $(TMAXDIR)/lib/sdl.o
LIBS = -lnsl -lsvr -lnodb
OBJS = $(AP_ORA_OBJS) $(AP_TBR_OBJS) $(SVCTOBJ) $(APOBJS)
SVCTOBJ = $(TARGET)_svctab.o
CFLAGS = -O -I$(TMAXDIR)
APPDIR = $(TMAXDIR)/appbin
SVCTDIR = $(TMAXDIR)/svct
TMAXLIBDIR = $(TMAXDIR)/lib
#
.SUFFIXES : .c
.c.o:
echo $(OBJS)
$(CC) $(CFLAGS) -c $<
#
# server compile
#
all: $(TARGET)
$(TARGET):$(OBJS)
echo $(OBJS)
$(CC) $(CFLAGS) -L$(TMAXLIBDIR) -o $(TARGET) -L$(TBRLIBDIR) -L$(ORALIBDIR) $(ORALIB) $(TBRLIB) $(OBJS) $(LIBS) $(NSDLOBJ)
mv $(TARGET) $(APPDIR)/.
rm -f $(OBJS)
$(AP_ORA_OBJS):
echo $(OBJS)
proc iname=$(TARGET)_ora.pc include=$(TMAXDIR)
$(CC) $(CFLAGS) -c $(TARGET)_ora.c
$(AP_TBR_OBJS):
echo $(OBJS)
tbpc iname=$(TARGET)_tbr.tbc include=$(TMAXDIR)
$(CC) $(CFLAGS) -I$(TBRINCDIR) -c $(TARGET)_tbr.c
$(APOBJS):
echo $(OBJS)
$(CC) $(CFLAGS) -c $(TARGET).c
$(SVCTOBJ):
echo $(OBJS)
cp -f $(SVCTDIR)/$(TARGET)_svctab.c .
touch ./$(TARGET)_svctab.c
$(CC) $(CFLAGS) -c ./$(TARGET)_svctab.c
#
clean:
-rm -f *.o core $(TARGET) $(TARGET).lis
The makefile content may be different for each operating system.
Two Oracle instances can be used in TCS through the server library. This section describes examples of programs that use two Oracle instances, environment configuration, and makefile for compilation.
The following example shows transaction processing on a single server that uses two Oracle RM instances.
Since the same Oracle client library is used, the user must specify the instance to use when executing a query from user code. For xa_open in Oracle, an OCI function, such as xaoSvcCtx or xaoEnv, can be used to obtain a connection to the desired instance.
The following is program source code that executes a service.
#include <stdio.h> #include <usrinc/atmi.h> extern int oracle_call(TPSVCINFO *msg); MDB_SVC2(TPSVCINFO *msg) { int ret; int fail = 0; ret = oracle_call(msg); if (ret < 0) { fail = 1; } if ( fail ) { tpreturn(TPFAIL,0,(char *)msg->data, msg->len,0); } tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0); }
The following program uses a function to call Oracle.
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tx.h> #include <oci.h> static void checkerr(errhp, status) OCIError *errhp; sword status; { text errbuf[512]; sb4 errcode; switch (status) { case OCI_SUCCESS: break; case OCI_SUCCESS_WITH_INFO: break; case OCI_NEED_DATA: break; case OCI_NO_DATA: break; case OCI_ERROR: /* get the error info and display it on the screen */ (void) OCIErrorGet ((dvoid *) errhp, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR); (void) printf("Error - %s\n", errbuf); break; case OCI_INVALID_HANDLE: break; case OCI_STILL_EXECUTING: break; case OCI_CONTINUE: break; default: break; } } int oracle_call(TPSVCINFO *msg) { int i; OCIEnv *envhp; OCIServer *srvhp; OCIError *errhp; OCISvcCtx *svchp; OCISession *usrhp; OCIStmt *stmthp; dvoid *tmp; char *sql = {"INSERT " "INTO hahehiho_account( account_id, address, phone ) " "VALUES ( skt_seq.nextval,'asdf', '007-1234' )"}; char *sql2 = {"INSERT " "INTO hahehiho_account( account_id, address, phone ) " "VALUES ( skt_seq.nextval,'fdsa', '700-1234' )"}; svchp = xaoSvcCtx("A"); envhp = xaoEnv("A"); printf("oracle call A octxt[%d]\n", svchp); OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, (ub4) OCI_HTYPE_ERROR, 52, (dvoid **) &tmp); OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmthp, (ub4) OCI_HTYPE_STMT, 50, (dvoid **) &tmp); checkerr(errhp, OCIStmtPrepare(stmthp, errhp,(text *)sql, (ub4)strlen(sql), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)); checkerr(errhp, OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)); svchp = xaoSvcCtx("B"); envhp = xaoEnv("B"); printf("oracle call B octxt[%d]\n", svchp); OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, (ub4) OCI_HTYPE_ERROR, 52, (dvoid **) &tmp); OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmthp, (ub4) OCI_HTYPE_STMT, 50, (dvoid **) &tmp); checkerr(errhp, OCIStmtPrepare(stmthp, errhp,(text *)sql2, (ub4)strlen(sql2), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)); checkerr(errhp, OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT)); return 0; }
The following shows the environment configuration and compilation of MultipleRM that uses two Oracle instances.
The following is a MultipleRM server configuration example.
*DOMAIN domain SHMKEY = 81522, MAXUSER = 10000, MINCLH = 1, MAXCLH = 1, TPORTNO = 11500, BLOCKTIME = 30, MAXSACALL = 1024, MAXCACALL = 1024, MAXMTMAX = 3, MAXSTMAX = 10 *NODE node1 TMAXDIR = "/home/tmax", APPDIR = "/home/tmax/appbin", PATHDIR = "/home/tmax/path", TLOGDIR = "/home/tmax/log/tlog", ULOGDIR = "/home/tmax/log/ulog", SLOGDIR = "/home/tmax/log/slog" *SVRGROUP svg_s1 NODENAME = node1, DBNAME = ORACLE, OPENINFO ="Oracle_Xa+SqlNet=TMAX1+Acc=P/scott/tiger+SesTm=60+DB=A", TMSNAME = tms_ora, SVGTYPE = STMAX, RMID = 0 svg_s2 NODENAME = node1, DBNAME = ORACLE, OPENINFO ="Oracle_Xa+SqlNet=TMAX2+Acc=P/scott/tiger+SesTm=60+DB=B", TMSNAME = tms_ora, SVGTYPE = STMAX, RMID = 1 svgm1 NODENAME = node1, SVGLIST = "svg_s2,svg_s1", SVGTYPE = MTMAX *SERVER sample SVGNAME = svgm1, LOGLVL = DEBUG4 *SERVICE MDB_SVC2 SVRNAME = sample
-lnodb must be included in the LIBS item of the makefile.
The following is a makefile that compiles a MultipleRM server program in 32bit Linux.
# Oracle Env
ORALIBDIR = /home/OraHome1/lib/
ORALIB = -lclntsh `cat /home/OraHome1/lib/ldflags` `cat /home/OraHome1/lib/sysliblist` -ldl -lm
LIBS = -lnsl -lsvrmrm
OBJS = $(AP_ORA_OBJS) $(AP_TBR_OBJS) $(SVCTOBJ) $(APOBJS)
SVCTOBJ = $(TARGET)_svctab.o
CFLAGS = -O -I$(TMAXDIR)
APPDIR = $(TMAXDIR)/appbin
SVCTDIR = $(TMAXDIR)/svctTARGET = $(COMP_TARGET)
APOBJS = $(TARGET).o
AP_ORA_OBJS = $(TARGET)_ora.o
NSDLOBJ = $(TMAXDIR)/lib/sdl.o
LIBS = -lnsl -lsvr -lnodb
OBJS = $(AP_ORA_OBJS) $(SVCTOBJ) $(APOBJS)
SVCTOBJ = $(TARGET)_svctab.o
CFLAGS = -O -I$(TMAXDIR) -I$(ORACLE_HOME)/include -I$(ORACLE_HOME)/rdbms/demo -I$(ORACLE_HOME)/rdbms/public
APPDIR = $(TMAXDIR)/appbin
SVCTDIR = $(TMAXDIR)/svct
TMAXLIBDIR = $(TMAXDIR)/lib
#
.SUFFIXES : .c
.c.o:
echo $(OBJS)
$(CC) $(CFLAGS) -c $<
#
# server compile
#
all: $(TARGET)
$(TARGET):$(OBJS)
$(CC) $(CFLAGS) -L$(TMAXLIBDIR) -o $(TARGET) -L$(ORALIBDIR) $(ORALIB) $(OBJS) $(LIBS) $(NSDLOBJ)
mv $(TARGET) $(APPDIR)/.
rm -f $(OBJS)
$(AP_ORA_OBJS):
$(CC) $(CFLAGS) -c $(TARGET)_ora.c
$(APOBJS):
$(CC) $(CFLAGS) -c $(TARGET).c
$(SVCTOBJ):
echo $(OBJS)
cp -f $(SVCTDIR)/$(TARGET)_svctab.c .
touch ./$(TARGET)_svctab.c
$(CC) $(CFLAGS) -c ./$(TARGET)_svctab.c
#
clean:
-rm -f *.o core $(TARGET) $(TARGET).lis
The makefile content may be different for each operating system.