| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6253 人关注过本帖, 1 人收藏
标题:tuxedo XA和FML 范例(连接oracle)
只看楼主 加入收藏
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
结帖率:77.78%
收藏(1)
 问题点数:0 回复次数:1 
tuxedo XA和FML 范例(连接oracle)
发现自从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"               /* TUXEDO Header File */
#include "fml32.h"
#include "userlog.h"            /* TUXEDO Header File */
#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 writes to the central TUXEDO message log */
   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的操作的应该可以自行解决。

[ 本帖最后由 khaz 于 2011-8-7 11:21 编辑 ]
搜索更多相关主题的帖子: oracle 客户端 tuxedo 爱好者 服务端 
2011-08-07 11:16
lsxlong123
Rank: 2
等 级:论坛游民
帖 子:21
专家分:16
注 册:2012-7-24
收藏
得分:0 
楼主做啥的,很强呀
2012-11-20 15:47
快速回复:tuxedo XA和FML 范例(连接oracle)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016430 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved