README
上传用户:xfwatch
上传日期:2020-12-14
资源大小:872k
文件大小:21k
- JBoss, Home of Professional Open Source
- Copyright 2009, Red Hat, Inc., and others contributors as indicated
- by the @authors tag. All rights reserved.
- See the copyright.txt in the distribution for a
- full listing of individual contributors.
- This copyrighted material is made available to anyone wishing to use,
- modify, copy, or redistribute it subject to the terms and conditions
- of the GNU Lesser General Public License, v. 2.1.
- This program is distributed in the hope that it will be useful, but WITHOUT A
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License,
- v.2.1 along with this distribution; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301, USA.
-
NOTE: You may like to create a backup of this folder before starting!
NOTE: If you are using IPv6 you will need to change any references to localhost in the btconfig.xml files to be localhost4 or 127.0.0.1
- 1. INTRODUCTION
- ===============
- This example shows how to use an XA compliant database with BlackTie and has been tested against
- ORACLE 11g or DB2 9.7.1.
- To compile in support for ORACLE you will need to pass a preprocessor macro called ORACLE
- to the BlackTie utility that generates executables (as explained below).
- To compile in support of DB2 you need to pass a preprocessor macro called DB2 to the BlackTie utility
- that generates executables (as explained below).
- The preprocessor symbol is purely for the examples use, BlackTie does not require this symbol in its
- internal libraries.
- To include a particular database during runtime you will need to update the BlackTie btconfig.xml file
- with information specific to the required database. The example xml files (in the linux and win32 directories)
- includes notes and examples on how to configure ORACLE and DB2 support. The instance names of databases
- refered to in btconfig.xml (specified in the open string) must match the names in the products
- array in the source file request.c.
- ORACLE ONLY
- Oracle 11g can be downloaded from:
- http://www.oracle.com/technology/software/products/database/index.html (tested on release 11.1.0.6.0)
- For all stages of this example it is recommended that you have set ORACLE_HOME to the distribution of
- ORACLE you have installed.
- IMPORTANT: You must NOT have ORACLE_SID set as we are using two resource managers in this example
- IMPORTANT: You must have the following databases initialized with example tables: ORCL and blacktie
- DB2 ONLY
- DB2 can be downloaded from:
- http://www-01.ibm.com/software/data/db2/linux-unix-windows/download.html (tested on release IBM DB2 Express-C 9.7)
- Install instructions are available at:
- http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=/com.ibm.db2.luw.qb.server.doc/doc/c0050562.html
- When you run the installer for DB2 Express-C choose "custom setup" and then also include the "Application Development Tools"
- IMPORTANT: The example assumes you have exported DB2DIR to the fully qualified include folder appropriate to your platform,
- e.g. /home/blacktie/sqllib and that DB2_LIB is set correctly eg $DB2DIR/lib on 64 bit systems and $DB2DIR/lib32 on 32 bit systems
- IMPORTANT: For all stages of this example it is recommended that you have sourced the DB2DIR/db2profile script to initialize
- the environment
- IMPORTANT: DB2 requires additional shared memory to run "sysctl -w kernel.shmmax=1024000000"
- IMPORTANT: If you are using multiple DB2 databases make sure they belong to the same "DB2 instance". A "DB2 instance" is a
- logical database server environment. This environment is controlled by setting the environment variable DB2INSTANCE to
- the user account that owns the DB2 server. For example, in linux, if you installed DB2 using a user account called blacktie
- then use
- export DB2INSTANCE=blacktie
- (if your application needs to use different server environments then you should run seperate blacktie servers for
- each target DB2 server environment.
- The example references two databases using alias names of BTDB1 and BTDB2 (if you are using different database aliases
- then remember to change them in btconfig.xml and reqest.c). Also note that aliases are case sensitive (in fact
- DB2 converts them to upper case) and 8 characters or less.
- For example, to create the DB2 databases using the DB2 command line tools:
- unix prompt> source <DB2 instance owners home dir>/sqllib/db2profile
- unix prompt> /opt/ibm/db2/V9.7/bin/db2
- Command Line Processor for DB2 Client 9.7.0
- db2 => db2start
- db2 => create database BTDB1
- db2 => create database BTDB2
- db2 => quit
-
- 2. BUILDING THE EXAMPLE
- =======================
- Make sure your environment is suitable for running BlackTie applications by sourcing the setenv scripts
- that came with the BlackTie distribution. On linux systems source:
- $BLACKTIE_HOME/setenv.sh
- and on windows execute:
- %BLACKTIE_HOME%setenv.bat
- On Windows:
- You MUST use an environment configured with the VC++ development tools, e.g. launch:
- C:Program FilesMicrosoft Visual Studio 9.0VCvcvarsall.bat
- To compile a BlackTie client and server use the generate_client and generate_server scripts that came with the
- distribution. The linux versions have a .sh suffix and windows versions have a .bat suffix.
- generate_client accepts arguments that specify which files to compile (-Dclient.includes=...), location of any required
- include directories (-Dx.inc.dir=) and the location of any required libraries (-Dx.lib.dir= and -Dx.libs=).
- [If you need to pass in more include directories and libraries use -Dx.inc.dir2=..., -Dx.lib.dir2=... and -Dx.libs2=...
- If you need even more, for example testing against three different resource manager products such as when testing recovery
- then use -Dx.inc.dir3=..., -Dx.lib.dir3=... and -Dx.libs3=...].
- It also accepts a list of preprocessor macro definitions (-Dx.define="comma separated list of macro names"). Thus, for example,
- to compile the client for use with Oracle11g:
- ORACLE ONLY
- -----------
- On Linux:
- generate_server.sh -Dservice.names=BAR -Dserver.includes="request.c ora.c DbService.c"
- -Dx.inc.dir="$ORACLE_HOME/rdbms/public"
- -Dx.lib.dir="$ORACLE_HOME/lib" -Dx.libs="occi clntsh"
- -Dx.define="ORACLE"
- Similarly for generating the client:
- generate_client.sh -Dclient.includes="client.c request.c ora.c cutil.c"
- -Dx.inc.dir="$ORACLE_HOME/rdbms/public"
- -Dx.lib.dir="$ORACLE_HOME/lib" -Dx.libs="occi clntsh"
- -Dx.define="ORACLE"
- On Windows:
- generate_server -Dservice.names=BAR -Dserver.includes="request.c ora.c DbService.c" -Dx.inc.dir="%ORACLE_HOME%OCIinclude" -Dx.lib.dir="%ORACLE_HOME%OCIlibMSVC" -Dx.libs="oci" -Dx.define="ORACLE"
- Similarly for generating the client:
- generate_client -Dclient.includes="client.c request.c ora.c cutil.c" -Dx.inc.dir="%ORACLE_HOME%OCIinclude" -Dx.lib.dir="%ORACLE_HOME%OCIlibMSVC" -Dx.libs="oci" -Dx.define="ORACLE"
- DB2 ONLY
- --------
- On Linux:
- generate_server.sh -Dservice.names=BAR -Dserver.includes="request.c db2.c DbService.c"
- -Dx.inc.dir="$DB2DIR/include"
- -Dx.lib.dir="$DB2_LIB" -Dx.libs="db2"
- -Dx.define="DB2"
- Similarly for generating the client:
- generate_client.sh -Dclient.includes="client.c request.c db2.c cutil.c"
- -Dx.inc.dir="$DB2DIR/include"
- -Dx.lib.dir="$DB2_LIB" -Dx.libs="db2"
- -Dx.define="DB2"
- On Windows:
- generate_server -Dservice.names=BAR -Dserver.includes="request.c db2.c DbService.c"
- -Dx.inc.dir="%DB2DIR%include"
- -Dx.lib.dir="%DB2_LIB%" -Dx.libs="db2api"
- -Dx.define="DB2"
- Similarly for generating the client:
- generate_client -Dclient.includes="client.c request.c db2.c cutil.c"
- -Dx.inc.dir="%DB2DIR%include"
- -Dx.lib.dir="%DB2_LIB%" -Dx.libs="db2api"
- -Dx.define="DB2"
- DB2 and ORACLE together
- -----------------------
- On Linux:
- generate_server.sh -Dservice.names=BAR -Dserver.includes="request.c db2.c ora.c DbService.c"
- -Dx.inc.dir="$ORACLE_HOME/rdbms/public"
- -Dx.inc.dir2="$DB2DIR/include"
- -Dx.lib.dir="$ORACLE_HOME/lib" -Dx.libs="occi clntsh"
- -Dx.lib.dir2="$DB2_LIB" -Dx.libs2="db2"
- -Dx.define="ORACLE,DB2"
- Similarly for generating the client:
- generate_client.sh -Dclient.includes="client.c request.c db2.c ora.c cutil.c"
- -Dx.inc.dir="$ORACLE_HOME/rdbms/public"
- -Dx.inc.dir2="$DB2DIR/include"
- -Dx.lib.dir="$ORACLE_HOME/lib" -Dx.libs="occi clntsh"
- -Dx.lib.dir2="$DB2_LIB" -Dx.libs2="db2"
- -Dx.define="ORACLE,DB2"
- On Windows:
- generate_server -Dservice.names=BAR -Dserver.includes="request.c ora.c DbService.c" -Dx.inc.dir="%ORACLE_HOME%OCIinclude" -Dx.inc.dir2="%DB2DIR%include" -Dx.lib.dir="%ORACLE_HOME%OCIlibMSVC" -Dx.libs="oci" -Dx.lib.dir2="%DB2_LIB%" -Dx.libs2="db2api" -Dx.define="ORACLE,DB2"
- Similarly for generating the client:
- generate_client -Dclient.includes="client.c request.c ora.c cutil.c" -Dx.inc.dir="%ORACLE_HOME%OCIinclude" -Dx.inc.dir2="%DB2DIR%include" -Dx.lib.dir="%ORACLE_HOME%OCIlibMSVC" -Dx.libs="oci" -Dx.lib.dir2="%DB2_LIB%" -Dx.libs2="db2api" -Dx.define="ORACLE,DB2"
- NOTE: If you get the following error you have not edited or executed setenv correctly:
- java org.apache.tools.ant.launch.Launcher -f /bin/generate-executables.xml -Dconfiguration.type=debug -Dbasedir=. -Dtoolchain.compiler=msvc server -Dservice.names=BAR -Dserver.includes="request.c ora.c DbService.c" -Dx.inc.dir="C:/<ora include dir>" -Dx.lib.dir="<ora lib dir>" -Dx.libs="occi.dll clntsh.dll" -Dx.define="ORACLE"
- Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/tools/ant/launch/Launcher
- Caused by: java.lang.ClassNotFoundException: org.apache.tools.ant.launch.Launcher
- at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
- at java.security.AccessController.doPrivileged(Native Method)
- at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
- at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
- at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
- at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
- at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
- Could not find the main class: org.apache.tools.ant.launch.Launcher. Program will exit.
- NOTE: On Windows - If you get the following error you have not used a command prompt with VC++ tools in it:
- BUILD FAILED
- C:blacktiedistblacktie-1.0-MR6-SNAPSHOTbingenerate-executables.xml:117: The following error occurred while executing this line:
- C:blacktiedistblacktie-1.0-MR6-SNAPSHOTbingenerate-executables.xml:144: Could not launch cl: java.io.IOException: Cannot run program "cl" (in directory "C:
- blacktiedistblacktie-1.0-MR6-SNAPSHOTexamplesxatmitxfooapptargetclasses"): CreateProcess error=2, The system cannot find the file specified
- 3. RUNNING THE EXAMPLE
- ======================
- Undeploy any older versions of the blacktie admin service
- Copy the file $BLACKTIE_HOME/blacktie-admin-services/blacktie-admin-services-<VERSION>-jar-with-dependencies.jar into $JBOSS_HOME/server/all/deploy
Copy the file $BLACKTIE_HOME/blacktie-admin-services/btconfig.xml into $JBOSS_HOME/server/all/conf
- Start the JBoss server (<JBOSS_HOME>/bin/run.sh|bat -c all)
- Make sure all required libraries are on the library path:
- ORACLE ONLY
- Something like
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib
- or
- set PATH=%PATH%;%ORACLE_HOME%bin
- DB2 ONLY
- Sourcing the db2profile should put the libraries in the path
- Alternatively:
- export DB2INSTANCE=blacktie
- export DB2_LIB=/home/mmusgrov/sqllib/lib32
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DB2_LIB
- or
- set PATH=%PATH%;%DB2DIR%lib
- BOTH
- As above with:
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DB2_LIB:$ORACLE_HOME/lib
- 3.1 START THE SERVER
- ====================
NOTE: You must NOT have ORACLE_SID set as we are using two resource managers in this example
- Edit the btconfig.xml to set REPLACE_WITH_INSTALL_LOCATION as appropriate
Edit the btconfig.xml to set REPLACE_WITH_HOSTNAME as appropriate
export BLACKTIE_CONFIGURATION=<win32|linux>
- export BLACKTIE_CONFIGURATION_DIR=serv
- btadmin startup
- 3.2 START THE CLIENT
- ====================
- NOTE: You must NOT have ORACLE_SID set as we are using two resource managers in this example
- Indicate which platform the client is running on:
- export BLACKTIE_CONFIGURATION=<win32|linux>
- ./client
- This runs a set of tests that exercise the various ways of interacting with resource managers. Please refer
- to the source file cutil.c to see what client/server/transaction combinations are used.
- [If you run more than one client from the same directory you will need to configure a unique recovery log name by
- setting the following environment variable:
- export BLACKTIE_RC_LOG_NAME=<unique file name>
- NOTE: If you get the following error it means you have not exported BLACKTIE_CONFIGURATION correctly:
- 2010-01-25 18:11:32,704 [0x7f805f2f5750] INFO (AtmiBrokerLogc :67 ) - TxLog setup: prod: ora - blacktie LOCAL DELETE AT SETUP
- 2010-01-25 18:11:32,722 [0x7f805f2f5750] WARN (AtmiBrokerLogc :91 ) - TxLog BAD REQ -1 db name: blacktie
- 2010-01-25 18:11:32,722 [0x7f805f2f5750] INFO (AtmiBrokerLogc :67 ) - TxLog setup: prod: ora - ORCL LOCAL DELETE AT SETUP
- 2010-01-25 18:11:32,723 [0x7f805f2f5750] WARN (AtmiBrokerLogc :91 ) - TxLog BAD REQ -1 db name: ORCL
- 2010-01-25 18:11:32,730 [0x7f805f2f5750] INFO (AtmiBrokerLogc :67 ) - TxLog Test failed (-1)
- 3.3 STOP THE SERVER
- ===================
btadmin shutdown
- 3.4 WHAT IF THE TESTS HANG
- ==========================
- The most likely cause is that the test is waiting on a Database lock held by in doubt transactions. Try resolving them
- using the tools that come with the database resource manager. For example, with DB2 run the interactive tool db2 and
- resolve using the command:
- db2 => LIST INDOUBT TRANSACTIONS WITH PROMPTING
- and for Oracle use, for example, sqlplus:
- sqlplus ....
- SQL> select LOCAL_TRAN_ID, STATE from DBA_2PC_PENDING;
- SQL> rollback force 'Oracle transaction id';
- APPENDIX: RECOVERY
- ==================
- To test recovery you will need to link against a library that is only available in the test suite (which you'll need to build
- from source - the library is called libtx-test-utilities.so).
- When building the client and server define the macro TX_RC as shown below. When the client runs it sends a request to
- the server that causes the server to generate a segmentation fault during the commit phase of the transaction commitment
- protocol. This will ensure that there is a pending transaction in need of recovery. See the note below about running
- select statements showing that one of the database instances got the commit but the other one will have the commit pending
- (ie the record will not be present until the transaction is recovered).
- [Note, to test failure after prepare but before the commit phase runs set TX_RC=2 when compiling the client
- (an example client compile line is shown below). This scenario should result in the transaction eventually being rolled back].
- Restart the server. The BlackTie log (blacktie.log) should show the system recovering the failed transaction. The expected
- message sequence is:
- An entry that indicates BlackTie is attempting the recovery with the following message (for each failed branch):
- "... Recovering resource with branch id: <branch id> and recovery IOR: ..."
- Then after one or two minutes the branch should attempt to commit with the following message:
- "... Commiting resource with branch id: <branch id>"
- Note also that the Transaction Manager running in the JBoss AS should report messages on the console. One to show the
- error that occurs when the server generates a segmentation fault during commit:
- "14:42:23,556 WARN [loggerI18N] [com.arjuna.ats.internal.jts.resources.rrcaught] ResourceRecord commit - caught exception: org.omg.CORBA.TRANSIENT: Retries exceeded, couldn't reconnect to 127.0.0.1:9032 vmcid: 0x0 minor code: 0 completed: No"
- and another message that indicates successful recovery of the pending transaction:
- "14:43:47,576 INFO [loggerI18N] [com.arjuna.ats.internal.jts.recovery.transactions.TransactionCache_5] [com.arjuna.ats.internal.jts.recovery.transactions.TransactionCache_5] - Transaction 7f000001:e2a7:4aadfb4c:a89 recovery completed"
- Required Configuration Changes:
- -------------------------------
- The XA resource that generates the segmentation fault needs to be included in btconfig.xml as follows:
- <XA_RESOURCE configuration="linux">
- <XA_RESOURCE_MGR_ID>202</XA_RESOURCE_MGR_ID>
- <XA_RESOURCE_NAME>DummyDb</XA_RESOURCE_NAME>
- <XA_OPEN_STRING></XA_OPEN_STRING>
- <XA_CLOSE_STRING></XA_CLOSE_STRING>
- <XA_SWITCH>testxasw</XA_SWITCH>
- <XA_LIB_NAME>libtx-test-utilities.so</XA_LIB_NAME>
- </XA_RESOURCE>
- Make sure that the XA_RESOURCE_MGR_ID lies between the two ORACLE Resource Manager ids. This will ensure that the
- ORACLE instance with the lower id will commit but the one with the higher id will not have committed.
- Similarly, if you need to test against DB2 then set the XA_RESOURCE_MGR_ID appropriately. For example, the default
- XA_RESOURCE_MGR_ID for testing against DB2 are 302 and 304 (see btconfig.xml) then use the value 303.
- The example needs to be compiled with the preprocessor definition TX_RC_RMID set to the correct XA_RESOURCE_MGR_ID
- (the default is 202).
- The test inserts an employee with id 8004 into the emp table. After running the client:
- select empno from emp where empno=8004; should return 1 record on the db with sid ORCL
- select empno from emp where empno=8004; should return 0 records on the db with sid blacktie.
- When the server is restarted and recovery is complete (should take a couple of minutes) retry the selects. This time
- both instances should return 1 record.
- Note that after failure the server needs to either restart on the same ORB endpoint (the easiest to configure)
- or needs to use a CORBA implementaton repository:
- - to use the same end point add something similar to the following in the ORBOPT environment entry (the portspan is required
- since the server can start more than one orb so a range of ports is necessary):
- <NAME>ORBOPT</NAME>
- <VALUE>-ORBListenEndpoints iiop://REPLACE_WITH_HOSTNAME:9032/portspan=10 -ORBInitRef ...</VALUE>
- - or to use an implementation repository:
- <NAME>ORBOPT</NAME>
- <VALUE>-ORBUseImR 1 -ORBInitRef ...</VALUE>
- Example command line for compiling and linking the server and client (defines the TX_RC macro and links against the
- dummy XA resource library):
- On Linux:
- generate_client.sh -Dclient.includes="client.c request.c ora.c cutil.c"
- -Dx.inc.dir="$HOME/blacktie/trunk/atmibroker-tx/target/cxx/test/include"
- -Dx.inc.dir2="$ORACLE_HOME/rdbms/public"
- -Dx.lib.dir="$HOME/blacktie/trunk/atmibroker-tx/target/cxx/test/lib" -Dx.libs="tx-test-utilities"
- -Dx.lib.dir2="$ORACLE_HOME/lib" -Dx.libs2="occi clntsh"
- -Dx.define="ORACLE, TX_RC"
- generate_server.sh -Dservice.names=BAR -Dserver.includes="request.c ora.c DbService.c"
- -Dx.inc.dir="$HOME/blacktie/trunk/atmibroker-tx/target/cxx/test/include"
- -Dx.inc.dir2="$ORACLE_HOME/rdbms/public"
- -Dx.lib.dir="$HOME/blacktie/trunk/atmibroker-tx/target/cxx/test/lib" -Dx.libs="tx-test-utilities"
- -Dx.lib.dir2="$ORACLE_HOME/lib" -Dx.libs2="occi clntsh"
- -Dx.define="ORACLE, TX_RC"
- [Note: If you need to test DB2 recovery you will need to add an extra preprocessor define (see comment above regarding the
- XA_RESOURCE_MGR_ID setting for the DummyDb resource manager):
- -Dx.define="ORACLE, TX_RC,TX_RC_RMID=302" ]
- On Windows:
- generate_client -Dclient.includes="client.c request.c ora.c cutil.c" -Dx.inc.dir="%ORACLE_HOME%OCIinclude" -Dx.lib.dir="%ORACLE_HOME%OCIlibMSVC" -Dx.libs="oci" -Dx.inc.dir2="c:/blacktie/trunk/atmibroker-tx/target/cxx/test/include" -Dx.lib.dir2="c:/blacktie/trunk/atmibroker-tx/target/cxx/test/lib" -Dx.libs2="tx-test-utilities" -Dx.define="ORACLE, TX_RC"
- generate_server -Dservice.names=BAR -Dserver.includes="request.c ora.c DbService.c" -Dx.inc.dir="%ORACLE_HOME%OCIinclude" -Dx.lib.dir="%ORACLE_HOME%OCIlibMSVC" -Dx.libs="oci" -Dx.inc.dir2="C:/blacktie/trunk/atmibroker-tx/target/cxx/test/include" -Dx.lib.dir2="c:/blacktie/trunk/atmibroker-tx/target/cxx/test/lib" -Dx.libs2="tx-test-utilities" -Dx.define="ORACLE, TX_RC"
- Note that the library path needs to include the location of the tx-test-utilities library. For example:
- On Linux:
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib:$HOME/blacktie/trunk/atmibroker-tx/target/cxx/test/lib
- On Windows:
- set PATH=%PATH%;%ORACLE_HOME%/bin;c:/blacktie/trunk/atmibroker-tx/target/cxx/test/lib
- Note that recovery implies that the various components in the system need to store state on disk. If things don't go according
- to plan you will need to either manually recover the transaction or, since this is only a demo example, manually
- clear the logs:
- BlackTie recovery log: fooapp* # safe to delete these logs
- JBossTS logs: $JBOSS_HOME/server/<server name>/data/tx-object-store/
- # probably not wise to delete these unless you know that there are no other transactions in the system