java 客户端调用 Tuxedo中间件
原文章地址
簡(jiǎn)介
Oracle Tuxedo服務(wù)可以使用純java來編寫。使用java實(shí)現(xiàn)的服務(wù)的功能和其他Tuxedo服務(wù)實(shí)現(xiàn)是一樣的。你可以使用客戶端或者Tuxedo服務(wù)器通過ATMI接口來調(diào)用Tuxedo Java Server(TMJSVASVR)對(duì)外提供的服務(wù);你也在java實(shí)現(xiàn)的服務(wù)中通過TJATMI接口來調(diào)用Tuxedo server提供的服務(wù)。
另外,你可以使用任何類型的Tuxedo客戶端調(diào)用java實(shí)現(xiàn)的服務(wù),比如本地客戶端,/WS客戶端和Jolt客戶端。
可以使用TJATMI接口、JATMI類型緩沖、POLO java對(duì)象等主流Java技術(shù)來實(shí)現(xiàn)Tuxedo服務(wù)。
編程方針
- Java服務(wù)類,實(shí)現(xiàn)Java服務(wù),需要繼承TuxedoJavaServer類;Java服務(wù)類應(yīng)該有一個(gè)默認(rèn)的構(gòu)造函數(shù)
- Java服務(wù)類中的Java方法會(huì)被向外提供成Java服務(wù),應(yīng)該聲明為public, 并將TPSVCINFO接口作為唯一的輸入?yún)?shù)
- Java服務(wù)類應(yīng)該實(shí)現(xiàn)tpsvrinit()方法,在Tuxedo Java服務(wù)啟動(dòng)時(shí)會(huì)被調(diào)用
- Java服務(wù)類應(yīng)該實(shí)現(xiàn)tpsvrdone()方法,在Tuxedo Java服務(wù)關(guān)閉時(shí)會(huì)被調(diào)用
- Java服務(wù)可以使用Tuxedo Java ATMI接口(例如tpcall,tpbegin等)
- Java服務(wù)可以使用tpreturn向客戶端返回結(jié)果,或者通過拋出異常退出
Tuxedo Java 服務(wù)器線程與Java類實(shí)例模型
- Tuxedo Java服務(wù)使用傳統(tǒng)的Tuxedo多線程模型,必須運(yùn)行在多線程模式下
- 一旦啟動(dòng),Tuxedo Java服務(wù)為每一個(gè)定義在配置文件中的類創(chuàng)建一個(gè)全局對(duì)象(實(shí)例),處理Java服務(wù)時(shí)工作線程共享全局對(duì)象(實(shí)例)
Tudexo Java服務(wù)器 tpsvrinit()/tpsvrdone()處理
tpsvrinit()處理:
用戶需要實(shí)現(xiàn)tpsvrinit()方法。由于該方法會(huì)在服務(wù)啟動(dòng)時(shí)調(diào)用,最好在該方法中完成類的初始化。如果一個(gè)類的tpsvrinit()方法失敗,用戶日志中會(huì)報(bào)告一條警告信息,Java服務(wù)會(huì)繼續(xù)執(zhí)行。
tpsvrdone()處理:
用戶需要實(shí)現(xiàn)tpsvrinit()方法。該方法在服務(wù)關(guān)閉時(shí)調(diào)用,推薦將類范圍的清理工作放入這個(gè)方法中。
Tuxedo Java服務(wù)器tpreturn()處理
Java服務(wù)的tpreturn()并不會(huì)立即結(jié)束Java服務(wù)方法的執(zhí)行,而是向Tuxedo Java服務(wù)器返回一個(gè)結(jié)果。
Java 服務(wù)的tpreturn()的行為與現(xiàn)有Tuxedo系統(tǒng)的tpreturn()行為不同:
- 當(dāng)現(xiàn)有Tuxedo系統(tǒng)調(diào)用tpreturn()時(shí),流控制自動(dòng)轉(zhuǎn)向Tuxedo
- 當(dāng)Java服務(wù)調(diào)用tpreturn()時(shí),tpreturn()之后的語(yǔ)句依舊會(huì)被執(zhí)行。用戶必須保證tpreturn()是Java服務(wù)中最后一條執(zhí)行的語(yǔ)句。如果不是,建議在tpreturn()之后加上return;否則tpreturn()不會(huì)自動(dòng)將流控制轉(zhuǎn)向Tuxedo系統(tǒng)
注意:不建議在Java服務(wù)中前面沒有tpreturn()時(shí)使用return。這種用法會(huì)使Java服務(wù)器返回rcode為0的TPFAIL到相關(guān)的客戶端。
Tuxedo Java服務(wù)器異常處理
- Java服務(wù)執(zhí)行期間可以拋出任何的異常然后退出Java服務(wù)。這種情況下Java服務(wù)器會(huì)返回TPFAIL到其客戶端,其中rcode設(shè)置為0
- 所有的異常信息會(huì)記錄在$APPDIR/stderr文件中。
編程環(huán)境
更新UBB配置文件
你需要配置一個(gè)路徑,通過該路徑Tuxdeo Java服務(wù)器可以找到CLOPT中Java實(shí)現(xiàn)的服務(wù)的配置文件。
由于ATMI Java服務(wù)器是一個(gè)多線程服務(wù)器,你還需要指名線程分配的限制。可以查看Defining the Server Dispatch Threads一章獲取更多關(guān)于多線程服務(wù)配置的信息。
清單2-1 顯示了ATMI Java服務(wù)器的UBB配置文件示例:
清單2-1
*SERVERS TMJAVASVR SRVGRP=TJSVRGRP SRVID=3 CLOPT="-- -c /home/oracle/app/javaserver/TJSconfig.xml" MINDISPATCHTHREADS=2 MAXDISPATCHTHREADS=3注意:UBBCONFIG中為Java服務(wù)器指明的MAXDISPATCHTHREADS最小值為2。
參見
- Setting Up an Oracle Tuxedo Application
- UBBCONFIG(5) in the File Formats, Data Descriptions, MIBs, and System Processes Reference
ATMI Java Server 用戶接口
TuxedoJavaServer
TuxedoJavaServer是一個(gè)抽象類,所有用戶定義的實(shí)現(xiàn)服務(wù)的類都應(yīng)該繼承它。
表3-1 TuxedoJavaServer接口
| tpsvrinit | 抽象方法,子類實(shí)現(xiàn)時(shí)做一些初始化的工作 |
| tpsvrdone | 抽象方法,子類實(shí)現(xiàn)時(shí)做一些清理工作 |
| getTuxAppContext | 用來取回當(dāng)前連接的Tuxedo應(yīng)用Java上下文 |
Oracle Tuxedo Java上下文
為了獲取Oracle Tuxedo Java Server提供的TJATMI原始功能,你需要獲取一個(gè)TuxAppContext對(duì)象,該對(duì)象實(shí)現(xiàn)了所有的TJATMI功能
因?yàn)榉?wù)類繼承自TuxedoJavaServer,你可以在服務(wù)中調(diào)用getTuxAppContext()方法獲取上下文對(duì)象。然而,你不能在tpsvrinit()中或其TuxAppContext,因?yàn)榇藭r(shí)TuxAppContext沒有準(zhǔn)備好。如果你在tpsvrinit()中嘗試獲取TuxAppContext,tpsvrinit()會(huì)出錯(cuò)并拋出異常。
Tuxedo Java 應(yīng)用中的TJATMI功能
TJATMI是原生功能的集合,提供客戶端和服務(wù)器端的通信功能,比如調(diào)用服務(wù),開始和結(jié)束事務(wù),獲取到數(shù)據(jù)源的連接,日志等等。更多信息參考Java Server Javadoc.
表3-2 TJATMI功能
| tpcall | 用于在請(qǐng)求/應(yīng)答通信中同步調(diào)用Oracle Tuxedo服務(wù) |
| tpreturn | 用于在Tuxedo Java Server中設(shè)置返回值 |
| tpbegin | 開始事務(wù) |
| tpcommit | 提交當(dāng)前事務(wù) |
| tpabort | 終止當(dāng)前事務(wù) |
| tpgetlev | 檢查事務(wù)是否正在執(zhí)行 |
| getConnection | 獲取到已配置的數(shù)據(jù)源的連接 |
| userlog | 在Tuxedo用戶日志文件中打印日志 |
注意:在tpreturn結(jié)束執(zhí)行后服務(wù)依舊在運(yùn)行。推薦把tpreturn作為服務(wù)中最后執(zhí)行的語(yǔ)句。
Tuxedo Java應(yīng)用的類型緩沖
ATMI Java server 重用了Oracle WebLogic Tuxedo Connector TypedBuffers 作為相應(yīng)的Oracle Tuxedo類型緩沖。消息通過類型緩沖傳入 server 。ATMI Java server提供的類型緩沖見表3-3:
表3-3 類型緩沖
| TypedString | 數(shù)據(jù)是以null字符作為結(jié)束的字符數(shù)組時(shí)使用。Oracle Tuxedo 等價(jià)類型:STRING |
| TypedCArray | 數(shù)據(jù)是未定義字符數(shù)組(字節(jié)數(shù)組),任一字節(jié)都有可能是null。Oracle Tuxedo等價(jià)類型:CARRAY |
| TypedFML | 數(shù)據(jù)自定義時(shí)使用。每個(gè)數(shù)據(jù)域攜帶自己的標(biāo)識(shí),事件數(shù),有可能有長(zhǎng)度指示器。Oracle Tuxedo等價(jià)類型:FML |
| TypedFML32 | 類似于TypedFML但是允許更大的字符范圍和域,更大的緩沖。Oracle Tuxedo等價(jià)類型:FML32 |
| TypedXML | 數(shù)據(jù)是基于XML的消息。Oracle Tuxedo等價(jià)類型:XML |
| TypedView | 應(yīng)用使用Java結(jié)構(gòu),使用視圖描述文件來定義緩沖結(jié)構(gòu)。Oracle Tuxedo等價(jià)類型:VIEW |
| TypedView32 | 類似于View,允許更大的字符范圍、域、緩沖。Oracle Tuxedo等價(jià)類型:VIEW32 |
更多關(guān)于類型緩沖的信息,參見"weblogic.wtc.jatmi"
類型緩沖支持的限制
- TypedFML32中Fldid()/Fname()嵌套在另一個(gè)TypedFML32中時(shí)無法工作。為了應(yīng)對(duì)這種情況,你可以使用fieldtable類傳輸name/id。
- 目前weblogic.wtc.gwt.XmlViewCnv/XmlFmlCnv類無法使用。
獲取/設(shè)置服務(wù)信息
使用TPSVCINFO類通過客戶端獲取/設(shè)置服務(wù)信息
表3-4 Getter函數(shù)
| getServiceData | 用來返回Oracle Tuxedo客戶端發(fā)送過來的服務(wù)數(shù)據(jù) |
| getServiceFlags | 用來返回客戶端發(fā)送過來的服務(wù)標(biāo)識(shí) |
| getServiceName | 用來返回調(diào)用的服務(wù)名 |
| getAppKey | 獲取程序認(rèn)證客戶端密鑰 |
| getClientID | 獲取客戶端標(biāo)識(shí)符 |
使用TuxATMIReply從服務(wù)請(qǐng)求中獲取回應(yīng)數(shù)據(jù)和元數(shù)據(jù)
表3-5 用于回應(yīng)的Getter函數(shù)
| getReplyBuffer | 返回從服務(wù)返回的類型緩沖(可能是null) |
| gettpurcode | 返回從服務(wù)返回的tpurcode |
異常
你需要捕獲服務(wù)中JATMI原語(yǔ)拋出的異常,比如tpcall()。JATMI可能拋出兩種類型的異常:
- TuxATMITPException:該異常拋出表明TJATMI出錯(cuò)
- TuxATMITPReplyException:如果服務(wù)出錯(cuò)(TPESVCFAIL或者TPSVCERROR)該異常拋出,用戶數(shù)據(jù)關(guān)聯(lián)到異常中。
跟蹤
你還需要導(dǎo)出TMTRACE=atmi:ulog,正如你使用傳統(tǒng)ATMI那樣。TJATMI API跟蹤信息被寫入U(xiǎn)LOG。
在Oracle Tuxedo Java Server 中實(shí)現(xiàn)服務(wù)
典型過程
- 使用getTuxAppContext()獲取TuxAppContext對(duì)象
- 使用TPSVCINFO.getServiceData()從TPSVCINFO對(duì)象中獲取客戶端請(qǐng)求數(shù)據(jù)
- 如果配置了數(shù)據(jù)源,使用TuxAppContext.getConnection()方法獲取到數(shù)據(jù)源的連接
- 完成商業(yè)邏輯,比如使用TuxAppContext.tpcall()調(diào)用其他服務(wù),操縱數(shù)據(jù)庫(kù)等
- 分配新的類型緩沖,把應(yīng)答數(shù)據(jù)放入類型緩沖中
- 調(diào)用TuxAppContext.tpreturn()將應(yīng)答數(shù)據(jù)返回客戶端
實(shí)例:沒有事務(wù)的Java服務(wù)實(shí)現(xiàn)
如下實(shí)例是實(shí)現(xiàn)TOUPPER服務(wù)的簡(jiǎn)單示例。
定義Java類
清單4-1
import weblogic.wtc.jatmi.TypedBuffer; import weblogic.wtc.jatmi.TypedString; import com.oracle.tuxedo.tjatmi.*; public class MyTuxedoJavaServer extends TuxedoJavaServer {public MyTuxedoJavaServer(){return;}public int tpsvrinit() throws TuxException{System.out.println("MyTuxedoJavaServer.tpsvrinit()");return 0;}public void tpsvrdone(){System.out.println("MyTuxedoJavaServer.tpsvrdone()");return;}public void JAVATOUPPER(TPSVCINFO rqst) throws TuxException {TypedBuffer svcData;TuxAppContext myAppCtxt = null;TuxATMIReply myTuxReply = null;TypedBuffer replyTb = null;/* Get TuxAppContext first */myAppCtxt = getTuxAppContext();svcData = rqst.getServiceData();TypedString TbString = (TypedString)svcData;myAppCtxt.userlog("Handling in JAVATOUPPER()");myAppCtxt.userlog("Received string is:" + TbString.toString());String newStr = TbString.toString();newStr = newStr.toUpperCase();TypedString replyTbString = new TypedString(newStr);/* Return new string to client */myAppCtxt.tpreturn(TPSUCCESS, 0, replyTbString, 0);}public void JAVATOUPPERFORWARD(TPSVCINFO rqst) throws TuxException {TypedBuffer svcData;TuxAppContext myAppCtxt = null;TuxATMIReply myTuxReply = null;TypedBuffer replyTb = null;long flags = TPSIGRSTRT;/* Get TuxAppContext first */myAppCtxt = getTuxAppContext();svcData = rqst.getServiceData();TypedString TbString = (TypedString)svcData;myAppCtxt.userlog("Handling in JAVATOUPPERFORWARD()");myAppCtxt.userlog("Received string is:" + TbString.toString());/* Call another service "TOUPPER" which may be implemented by another Tuxedo Server */try {myTuxReply = myAppCtxt.tpcall("TOUPPER", svcData, flags);/* If success, get reply buffer */replyTb = myTuxReply.getReplyBuffer();TypedString replyTbStr = (TypedString)replyTb;myAppCtxt.userlog("Replied string from TOUPPER:" + replyTbStr.toString());/* Return the replied buffer to client */myAppCtxt.tpreturn(TPSUCCESS, 0, replyTb, 0);} catch (TuxATMITPReplyException tre) {myAppCtxt.userlog("TuxATMITPReplyException:" + tre);myAppCtxt.tpreturn(TPFAIL, 0, null, 0);} catch (TuxATMITPException te) {myAppCtxt.userlog("TuxATMITPException:" + te);myAppCtxt.tpreturn(TPFAIL, 0, null, 0);}} }創(chuàng)建Java Server配置文件
清單4-2顯示了配置示例,將MyTuxedoJavaServer.JAVATOUPPER()方法導(dǎo)出成Tuxedo 服務(wù)JAVATOUPPER,將MyTuxedoJavaServer.JAVATOUPPERFORWARD()方法導(dǎo)出成Tuxedo 服務(wù)JAVATOUPPERFORWARD。
清單4-2
<?xml version="1.0" encoding="UTF-8"?> <TJSconfig><TuxedoServerClasses><TuxedoServerClass name="MyTuxedoJavaServer"> </TuxedoServerClass></TuxedoServerClasses> </TJSconfig>更新UBB配置文件
清單4-3 UBB配置文件
*GROUPS TJSVRGRP LMID=simple GRPNO=2 *SERVERS TMJAVASVR SRVGRP= TJSVRGRP SRVID=4 CLOPT="-- -c TJSconfig.xml" MINDISPATCHTHREADS=2 MAXDISPATCHTHREADS=2實(shí)例:帶有事務(wù)的Java Service實(shí)現(xiàn)
清單4-4給出了一個(gè)示例,實(shí)現(xiàn)WRITEDB_SVCTRN_COMMIT服務(wù),該服務(wù)將用戶請(qǐng)求字符串插入表TUXJ_TRAN_TEST中。
定義Java類
清單4-4
import weblogic.wtc.jatmi.TypedBuffer; import weblogic.wtc.jatmi.TypedString; import com.oracle.tuxedo.tjatmi.*; import java.sql.SQLException; /* MyTuxedoTransactionServer is user defined class */ public class MyTuxedoTransactionServer extends TuxedoJavaServer{public MyTuxedoTransactionServer (){return;}public int tpsvrinit() throws TuxException{System.out.println("In MyTuxedoTransactionServer.tpsvrinit()");return 0;}public void tpsvrdone(){System.out.println("In MyTuxedoTransactionServer.tpsvrdone()");return;}public void WRITEDB_SVCTRN_COMMIT(TPSVCINFO rqst) throws TuxException {TuxAppContext myAppCtxt;TypedBuffer rplyBuf = null;String strType = "STRING";String ulogMsg;TypedString rqstMsg;Connection connDB = null;Statement stmtDB = null;String stmtSQL;int trnLvl, trnStrtInSVC;int trnRtn;int rc = TPSUCCESS;rqstMsg = (TypedString)rqst.getServiceData();myAppCtxt = getTuxAppContext();myAppCtxt.userlog("JAVA-INFO: Request Message Is \"" + rqstMsg.toString() + "\"");rplyBuf = new TypedString("This Is a Simple Transaction Test from Tuxedo Java Service");long trnFlags = 0;try {trnStrtInSVC = 0;trnLvl = myAppCtxt.tpgetlev();if (0 == trnLvl) {long trnTime = 6000;myAppCtxt.userlog("JAVA-INFO: Start a transaction...");trnRtn = myAppCtxt.tpbegin(trnTime, trnFlags);myAppCtxt.userlog("JAVA-INFO: tpbegin return " + trnRtn);trnStrtInSVC = 1;}connDB = myAppCtxt.getConnection();if (null != connDB) {myAppCtxt.userlog("JAVA-INFO: Get connection: (" + connDB.toString() + ").");}stmtDB = connDB.createStatement();if (null != stmtDB) {myAppCtxt.userlog("JAVA-INFO: Create statement: (" + stmtDB.toString() + ").");}stmtSQL = "INSERT INTO TUXJ_TRAN_TEST VALUES ('" + rqstMsg.toString() + "')";myAppCtxt.userlog("JAVA-INFO: Start to execute sql (" + stmtSQL + ")...");stmtDB.execute(stmtSQL);myAppCtxt.userlog("JAVA-INFO: End to execute sql (" + stmtSQL + ").");if (1 == trnStrtInSVC) {myAppCtxt.userlog("JAVA-INFO: tpcommit current transaction...");trnRtn = myAppCtxt.tpcommit(trnFlags);myAppCtxt.userlog("JAVA-INFO: tpcommit return " + trnRtn);trnStrtInSVC = 0;if (-1 == trnRtn ) {rc = TPFAIL;}}} catch (TuxATMIRMException e) {String errMsg = "ERROR: TuxATMIRMException: (" + e.getMessage() + ").";myAppCtxt.userlog("JAVA-ERROR: " + errMsg);rc = TPFAIL;} catch (TuxATMITPException e) {String errMsg = "ERROR: TuxATMITPException: (" + e.getMessage() + ").";myAppCtxt.userlog("JAVA-ERROR: " + errMsg);rc = TPFAIL;} catch (SQLException e) {String errMsg = "ERROR: SQLException: (" + e.getMessage() + ").";myAppCtxt.userlog("JAVA-ERROR: " + errMsg);rc = TPFAIL;} catch (Exception e) {String errMsg = "ERROR: Exception: (" + e.getMessage() + ").";myAppCtxt.userlog("JAVA-ERROR: " + errMsg);rc = TPFAIL;} catch (Throwable e) {String errMsg = "ERROR: Throwable: (" + e.getMessage() + ").";myAppCtxt.userlog("JAVA-ERROR: " + errMsg);rc = TPFAIL;} finally {if (null != stmtDB) {try {stmtDB.close();} catch (SQLException e) {}}}myAppCtxt.tpreturn(rc, 0, rplyBuf, 0);} }創(chuàng)建Java 服務(wù)配置文件
表4-5
<?xml version="1.0" encoding="UTF-8"?> <TJSconfig><ClassPaths><ClassPath>/home/oracle/app/oracle/product/11.2.0/dbhome_2/ucp/lib/ucp.jar</ClassPath><ClassPath>/home/oracle/app/oracle/product/11.2.0/dbhome_2/jdbc/lib/ojdbc6.jar</ClassPath></ClassPaths><DataSources><DataSource name="oracle"><DriverClass>oracle.jdbc.xa.client.OracleXADataSource</DriverClass><JdbcDriverParams><ConnectionUrl>jdbc:oracle:thin:@//10.182.54.144:1521/javaorcl</ConnectionUrl></JdbcDriverParams></DataSource></DataSources><TuxedoServerClasses><TuxedoServerClass name=" MyTuxedoTransactionServer"></TuxedoServerClass></TuxedoServerClasses> </TJSconfig>更新UBB配置文件
清單4-6
*GROUPS ORASVRGRP LMID=simple GRPNO=1 OPENINFO="Oracle_XA:Oracle_XA+Acc=P/scott/triger+SesTm=120+MaxCur=5+LogDir=.+SqlNet=javaorcl" TMSNAME=TMSORA TMSCOUNT=2 *SERVERS TMJAVASVR SRVGRP=ORASVRGRP SRVID=3CLOPT="-- -c TJSconfig.xml"MINDISPATCHTHREADS=2 MAXDISPATCHTHREADS=4總結(jié)
以上是生活随笔為你收集整理的java 客户端调用 Tuxedo中间件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【columnstore】mariadb
- 下一篇: 【安卓作业】星座查询小程序