[转帖]   tuxedo XA和FML 范例(连接oracle)_MQ, Tuxedo及OLTP讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MQ, Tuxedo及OLTP讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4220 | 回复: 0   主题: [转帖]   tuxedo XA和FML 范例(连接oracle)        下一篇 
    本主题由 chong.zhang 于 2014-9-26 18:00:43 合并
匿名用户
发表于: IP:您无权察看 2013-3-14 9:44:11 | [全部帖] [楼主帖] 楼主

发现自从2008年oracle收购bea后,TUXEDO交易中间件的文章是越来越少了,感觉oracle并没有把它很好的发扬光大,然而我们公司会一直使用它,因为它的确太优秀,几乎所有核心系统、重要系统都使用它,公司内部对它都很熟悉,而且世界500强很多企业也在用它,所以,在学习了之后,本人把一个范例在这里分享。也希望对一些tuxedo爱好者有所帮助。
题目:
编写一个TUXEDO服务端程序,要求提供如下服务: 对客户端传送过来的数据进行处理,在数据格式正确的情况下插入到scott用户的dept表中,并给客户端应答。同时编写一个客户端程序,以命令行参数的形式传送需要插表的数据。 如:运行客户端程序: ./clientinsert 15 fred nanning 则15 fred nanning这3个值将插入数据库中,并且根据处理结果显��:插入成功或者失败。
本例环境:redflag DC server 5.0 + TUXEDO10gR3 + oracle10g
需要对oracle自带用户scott解锁,本例使用scott用户的相关表和应用用户hwt作为范例。
说明:#打头的命令表明以root用户执行,$打头的是以应用用户或者oracle用户执行。
有疑问可以加我QQ:68053651 欢迎交流
一、ORACLE配置

Oracle用户下,用sysdba帐户登陆数据库,

SQL> conn / as sysdba
SQL> @$ORACLE_HOME/rdbms/admin/xaview.sql
DROP VIEW v$xatrans$
*
ERROR at line 1:
ORA-00942: table or view does not exist
DROP VIEW v$pending_xatrans$
*
ERROR at line 1:
ORA-00942: table or view does not exist
View created.
View created.
SQL> grant select on v$xatrans$ to public with grant option;
Grant succeeded.
SQL> grant select on v$pending_xatrans$ to public with grant option;
Grant succeeded.
SQL> grant select any table to public;
Grant succeeded.
SQL>alter user scott account unlock;
SQL> grant dba to scott; //此步也许不是合理的解决方法,dba权限不该轻易给应用用户,看看还有什么方法可以代替的(网上说增加select 权限,但本人尝试未成功)。


在$ORACLE_HOME/precomp/admin/pcscfg.cfg中的sys_include里添加如下内容:/opt/app/oracle/product/10.2.0/db_1/precomp/public

二、重命名下列文件,因为下列文件名与ORACLE带的文件名有冲突,所以要改名。 
(1)TUXEDO安装路径include目录下的下面文件 

#mv sqlca.h sqlca.h.bbb
#mv sqlcode.h sqlcode.h.bbb
#mv sqlda.h sqlda.h.bbb


(2)重命名TUXEDO安装路径lib目录下的下面文件 (如果文件不存在可忽略)

mv libsql.lib libsql.lib.bbb


(3)重命名/usr/lib下的文件

mv libclntsh.so.10.1 libclntsh.so.10.1.bbb


三、TUXEDO的配置

1、修改$TUXDIR/udataobj/RM文件(TUXEDO10gR3不用做此步骤)
把原来的以Oracle_XA:xaosw:开头的屏蔽掉、
添加Oracle_XA:xaosw:-L${ORACLE_HOME}/lib -lclntsh

确保应用用户能够访问$ORACLE_HOME,同时把应用用户加入oracle的oinstall组(root用户执行)

#. /home/oracle/.bash_profile
#chmod -R 755 $ORACLE_HOME
#usermod -G oinstall -g hwt hwt


然后将oracle用户的.bash_profile内容添加至应用用户的.bash_profile 
即,hwt的.bash_profile内容为(请根据自己机器进行配置,建议以root用户在vi里用命令:r /home/oracle/.bash_profile的方式导入文本):

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
# added by oranavi
export ORACLE_BASE=/opt/app/oracle
export ORACLE_HOME=/opt/app/oracle/product/10.2.0/db_1
export ORACLE_SID=testdb
export NLS_LANG="Simplified Chinese_CHINA.ZHS16GBK"
export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
export PATH=$PATH:$ORACLE_HOME/bin
export ORACLE_DOC=$ORACLE_HOME/doc
CLASSPATH=$ORACLE_HOME/jre:$ORACLE_HOME/JRE
CLASSPATH=$CLASSPATH:$ORACLE_HOME/jlib
CLASSPATH=$CLASSPATH:$ORACLE_HOME/rdbms/jlib
CLASSPATH=$CLASSPATH:$ORACLE_HOME/jdbc/lib/classes12.jar
CLASSPATH=$CLASSPATH:$ORACLE_HOME/jdbc/lib/nls_charset12.jar
export CLASSPATH
LD_LIBRARY_PATH=$ORACLE_HOME/lib:$ORACLE_HOME/ctx/lib
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/jdbc/lib
export LD_LIBRARY_PATH
unset LANG
ulimit -n 65536 > /dev/null 2>&1
ulimit -u 16384 > /dev/null 2>&1
PATH=$PATH:$HOME/bin
export PATH
unset USERNAME


设置环境变量

ORACLE_HOME=/opt/app/oracle/product/10.2.0/db_1;export ORACLE_HOME
TUXDIR=/tuxedo10/tuxedo10gR3;export TUXDIR
APPDIR=/home/hwt/tuxint;export APPDIR
export PATH=.:$ORACLE_HOME:$ORACLE_HOME/bin:$TUXDIR/bin:$APPDIR:$PATH
TUXCONFIG=$APPDIR/tuxconfig;export TUXCONFIG
LD_LIBRARY_PATH=$ORACLE_HOME/lib:$TUXDIR/lib;export LD_LIBRARY_PATH
FIELDTBL32=fmlfile;export FIELDTBL32
FLDTBLDIR32=$APPDIR;export FLDTBLDIR32


生效环境变量:

. ./setenv.sh


创建TMS文件:TMS_ORA,TUXEDO通过TMS_ORA与ORACLE数据库采用XA协议进行通讯 

#chmod -R 755 $TUXDIR(这里注意如果$TUXDIR没有生效 需要写绝对路径)
$buildtms -o $TUXDIR/bin/TMS_ORA -r Oracle_XA


配置ubb

*RESOURCES
IPCKEY 210451
DOMAINID simpapp
MASTER simple
MAXACCESSERS 10
MAXSERVERS 20
MAXSERVICES 30
MODEL SHM
LDBAL N
SCANUNIT 10
BLOCKTIME 5
*MACHINES
DEFAULT:
APPDIR="/home/hwt/tuxint"
TUXCONFIG="/home/hwt/tuxint/tuxconfig"
TLOGNAME=TLOG
TUXDIR="/tuxedo10/tuxedo10gR3"
TLOGDEVICE="/home/hwt/tuxint/TLOG"
TLOGSIZE=150
localhost LMID=simple
*GROUPS
GROUP1
LMID=simple GRPNO=1 OPENINFO=NONE
ORAGRP
LMID=simple GRPNO=5
OPENINFO="Oracle_XA:Oracle_XA+Acc=P/scott/scott+SesTm=120+SqlNet=testdb+LogDIR=."
CLOSEINFO=""
TMSNAME=TMS_ORA TMSCOUNT=5
*SERVERS
DEFAULT:
CLOPT="-A"
svrInsert SRVID=10 SRVGRP=ORAGRP
*SERVICES
#INSERT


编译ubb:

$tmloadcf -y ubb
6、


创建TLOG:

tmadmin<<!
crdl -b 300 -z "/home/hwt/tuxint/TLOG"
crlog -m simple
!


这里300一般为TLOGSIZE两倍左右

fmlfile:
*base 500
DEPTNO 1 long - -
DNAME 2 string - -
LOC 3 string - -


客户端程序clientinsert:

#include <stdio.h>
#include "atmi.h"
#include "fml32.h"
#include "userlog.h"
#include "fmlfile.h"
int main(int argc, char *argv[])
{
      if (argc != 4) {
            (void) fprintf(stderr, "usage:%s value1 value2 value3\n", argv[0]);
            (void) exit(1);
      }
      if((strlen(argv[1])>2) (strlen(argv[2])>13) (strlen(argv[1])>12)){
            fprintf(stderr,"input string too long!\n");
            exit(1);
      }
      FBFR32 *pF32, *pF32rec;
      long len;
      if (tpinit((TPINIT *) NULL) == -1) {
            (void) fprintf(stderr,
            "Failed to join application -- %s\n",
            tpstrerror(tperrno));
            (void)
            userlog
            ("Clientfml failed to join application -- %s\n",
            tpstrerror(tperrno));
            (void) exit(1);
      }
      if ((pF32 = (FBFR32 *) tpalloc("FML32", NULL, 1024)) == NULL) {
            (void) fprintf(stderr,
            "Failure to allocate FML32 buffer -- %s\n",
            tpstrerror(tperrno));
            (void)
            userlog
            ("Clientfml failed to allocate FML32 buffer -- %s\n",
            tpstrerror(tperrno));
            (void) tpterm();
            (void) exit(1);
      }
      if ((pF32rec = (FBFR32 *) tpalloc("FML32", NULL, 1024)) == NULL) {
            (void) fprintf(stderr,
            "Failure to allocate FML32 buffer -- %s\n",
            tpstrerror(tperrno));
            (void)
            userlog
            ("Clientfml failed to allocate FML32 buffer -- %s\n",
            tpstrerror(tperrno));
            (void) tpterm();
            (void) exit(1);
      }
      int v = atoi(argv[1]);
      if (Fchg32(pF32, DEPTNO, -1, (char *) &v, (FLDLEN32) 0) == -1) {
            (void) fprintf(stderr,
            "Failure to change DEPTNO field -- %s\n",
            Fstrerror32(Ferror32));
            (void)
            userlog
            ("Clientfml failed to change DEPTNO field -- %s\n",
            Fstrerror32(Ferror32));
            (void) tpfree((char *) pF32);
            (void) tpfree((char *) pF32rec);
            (void) tpterm();
            (void) exit(1);
      }
      if (Fchg32(pF32, DNAME, -1, (char *) argv[2], (FLDLEN32) 0) == -1) {
            (void) fprintf(stderr,
            "Failure to change DNAME field -- %s\n",
            Fstrerror32(Ferror32));
            (void)
            userlog
            ("Clientfml failed to change DNAME field -- %s\n",
            Fstrerror32(Ferror32));
            (void) tpfree((char *) pF32);
            (void) tpfree((char *) pF32rec);
            (void) tpterm();
            (void) exit(1);
      }
      if (Fchg32(pF32, LOC, -1, (char *) argv[3], (FLDLEN32) 0) == -1) {
            (void) fprintf(stderr,
            "Failure to change LOC field -- %s\n",
            Fstrerror32(Ferror32));
            (void)
            userlog
            ("Clientfml failed to change LOC field -- %s\n",
            Fstrerror32(Ferror32));
            (void) tpfree((char *) pF32);
            (void) tpfree((char *) pF32rec);
            (void) tpterm();
            (void) exit(1);
      }
      if (tpcall
      ("INSERT", (char *) pF32, 0, (char **) &pF32rec, (long *) &len,
      0) == -1) {
            (void) fprintf(stderr, "插入失败!\n");
            tpstrerror(tperrno);
            (void)
            userlog
            ("Clientfml failed to call the INSERT service -- %s \n",
            tpstrerror(tperrno));
            (void) tpfree((char *) pF32);
            (void) tpfree((char *) pF32rec);
      } else {
      fprintf(stderr, "插入成功!\n");
      //FLDLEN32 len2;
      int deptno;
      char dname[15];
      char loc[14];
      //len2 = (FLDLEN32) sizeof(deptno);
      if(-1==Fget32(pF32rec, DEPTNO, 0, (char *) &deptno, NULL)){
            fprintf(stderr,"err in Fget32--deptno\n");
            exit(3);
      }
      //len2 = (FLDLEN32) sizeof(dname);
      if(-1==Fget32(pF32rec, DNAME, 0, (char *) dname, NULL)){
            fprintf(stderr,"err in Fget32--dname\n");
            exit(3);
      }
      //len2 = (FLDLEN32) sizeof(loc);
      if(-1==Fget32(pF32rec, LOC, 0, (char *) loc, NULL)){
            fprintf(stderr,"err in Fget32--loc\n");
            exit(3);
      }
      fprintf(stdout, "received the server's reply:\n");
      fprintf(stdout, "%d\n%s\n%s\n", deptno, dname, loc);
}
(void) tpfree((char *) pF32);
(void) tpfree((char *) pF32rec);
(void) tpterm();
exit(0);
}


服务端程序svrInsert.pc:

#include <stdio.h>
#include "atmi.h"
#include "fml32.h"
#include "userlog.h"
#include "fmlfile.h"
#include "sqlca.h"
//EXEC SQL INCLUDE sqlca;
EXEC SQL BEGIN DECLARE SECTION;
int deptno;
char dname[15];
char loc[14];
EXEC SQL END DECLARE SECTION;
tpsvrinit(int argc, char *argv[])
{
      argc = argc;
      argv = argv;
      userlog("Welcome to the simple server");
      if (tpopen() == -1) {
            userlog("connect to Oracle error\n");
            return -1;
      } else
      userlog("connect to Oracle normal\n");
      if (sqlca.sqlcode != 0) {
            userlog("%d:%-70s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
            tpreturn(TPFAIL, 0, NULL, 0, 0);
      }
      return (0);
}
INSERT(TPSVCINFO * rqst)
{
      FBFR32 *pfBuf;
      //FLDLEN32 len;
      pfBuf = (FBFR32 *) rqst->data;
      //len = (FLDLEN32) sizeof(deptno); 反复使用同一个len做Fget32要小心
      Fget32(pfBuf, DEPTNO, 0, (char *) &deptno, NULL);
      //len = (FLDLEN32) sizeof(dname);
      Fget32(pfBuf, DNAME, 0, (char *) dname, NULL);
      //len = (FLDLEN32) sizeof(loc);
      Fget32(pfBuf, LOC, 0, (char *) loc, NULL);
      userlog("\ndeptno=%d\ndname=%s\nloc=%s\n",deptno,dname,loc);
      tpbegin(10, 0);
      EXEC SQL INSERT INTO dept VALUES(:deptno,:dname,:loc);
      if (sqlca.sqlcode != 0) {
            userlog("%d:%-70s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
            tpreturn(TPFAIL, 0, NULL, 0, 0);
      }
      tpcommit(0);
      tpreturn(TPSUCCESS, 0,(char *)rqst->data, 0L, 0);
}
void tpsvrdone()
{
if (tpclose() == -1) {
      userlog("disconnect to Oracle error\n");
      return;
}
}


用Makefile编译 :

PC=proc
CC=gcc
CFLAGS=-I${ORACLE_HOME}/precomp/public -I${TUXDIR}/include -L$(ORACLE_HOME)/lib -L$(TUXDIR)/lib #-lclntsh -lecpg
PCFLAGS=include=${ORACLE_HOME}/precomp/public include=${TUXDIR}/include sqlcheck=none ltype=none parse=none
TUXCOF=tuxconfig
FILES=fmlfile.h
.SUFFIXES: .pc .c .o
.pc.c:
$(PC) $(PCFLAGS) $<
.c.o:
$(CC) $(CFLAGS) -c $<
.pc.o:
$(PC) $(PCFLAGS) $<
$(CC) $(CFLAGS) -c $(<:.pc=.c)
DEST = svrInsert \
clientinsert
INTERIM=$(DEST:=.o.c)
all: $(FILES) $(TUXCOF) $(DEST)
tuxconfig: ubb
tmloadcf -y ubb
fmlfile.h: fmlfile
mkfldhdr32 fmlfile
clientinsert: clientinsert.o
buildclient -o clientinsert -f clientinsert.o -v
svrInsert:svrInsert.o
buildserver -v -o svrInsert -f svrInsert.o -s INSERT -r Oracle_XA
clean:
-rm -f $(DEST) $(FILES) $(TUXCOF) *.o tp* svrInsert.c


使用make命令编译即可。

最后说明一下,关于环境变量的配置,可能不一定能够考虑周全,至少本人机器上是通过的,如果找不到命令,一般是环境变量问题,熟悉linux的操作的应该可以自行解决。



赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论