JTA/JDBC coordination using WebSphere MQ base Java

 


WebSphere MQ base Java supports the MQQueueManager.begin() method, which allows WebSphere MQ to act as a coordinator for a database which provides a JDBC 2 compliant driver. Currently this support is available on Solaris, AIX, and Windows systems with Oracle or DB2 databases.

 

Installation

In order to use the XA-JTA support, use the special JTA switch library. The method for using this library varies depending on whether you are using Windows systems or one of the other platforms.

 

Installation on Windows systems

On Windows systems, the new XA library is supplied as a complete DLL. The name of this DLL is jdbcxxx.dll where xxx indicates the database for which the switch library has been compiled. This library is in the java/lib/jdbc directory of your WebSphere MQ base Java installation.

 

Installation on other platforms

The switch file is supplied as an object file that link yourself using the supplied makefile. This is necessary because certain libraries required by the switch library might be in different locations on different systems. Because the switch library is loaded by the queue manager, which runs in a setuid environment, you cannot use the dynamic library path variable to locate these libraries. You therefore need to put the full path names to these libraries in the switch library itself.

The object files are called jdbcxxx.o where xxx indicates which database the object file is for. When linked, a switch file called jdbcxxx is produced; add this to the qm.ini file in the same manner as the standard switch libraries.

To create the switch library, go into the java/lib/jdbc subdirectory of your WebSphere MQ base Java installation and run make with your target database as a parameter. Currently supported targets for XA-JTA are oracle and db2. For example:

  make db2

The makefiles are set up to link against the databases and JDKs in their standard installed location. The exception to this is Oracle, which can be installed anywhere on the system. The makefile uses Oracle's ORACLE_HOME environment variable to link the library correctly. If your JDK is in a non-standard location, you can override the default directory with the JAVA_HOME definition:

  make JAVA_HOME=/usr/my_jdk13 oracle

The above command produces a switch file named jdbcora, which is used in the same way as a standard switch library, including using the same XAOpenString. If you have previously configured an XAResourceManager in your qm.ini, replace the SwitchFile line with a reference to the new JTA-specific switch file. If you have not previously used an XA switch file, refer to the WebSphere MQ System Administration Guide for of configuring the XAResourceManager stanza for different databases, remembering to replace the standard switch file with the Java-specific one.

Once you have updated the qm.ini, restart the queue manager. Ensure that all appropriate database environment variables have been set before calling strmqm.

 

Usage

The basic sequence of API calls for a user application is:

  qMgr = new MQQueueManager("PARIS")
  Connection con = qMgr.getJDBCConnection( xads );
  qMgr.begin()
 
 < Perform MQ and DB operations to be grouped in a unit of work >
 
  qMgr.commit() or qMgr.backout();
  con.close()
  qMgr.disconnect()

xads in the getJDBCConnection call is a database-specific implementation of the XADataSource interface, which defines the details of the database to connect to. See the documentation for your database to determine how to create an appropriate XADataSource object to pass into getJDBCConnection.

You also need to update your CLASSPATH with the appropriate database-specific jar files for performing JDBC work.

To connect to multiple databases, you might have to call getJDBCConnection several times to perform the transaction across several different connections.

There are two forms of the getJDBCConnection, reflecting the two forms of XADataSource.getXAConnection:

  public java.sql.Connection getJDBCConnection javax.sql.XADataSource(xads)
    throws MQException, SQLException, Exception
 
  public java.sql.Connection getJDBCConnection(XADataSource dataSource,
                                            String userid, String password)
    throws MQException, SQLException, Exception

These methods declare Exception in their throws clauses to avoid problems with the JVM verifier for customers who are not using the JTA functionality. The actual exception thrown is javax.transaction.xa.XAException. which requires the jta.jar file to be added to the classpath for programs that did not previously require it.

 

Known problems and limitations

Because this support makes calls to JDBC drivers, the implementation of those JDBC drivers can have significant impact on the system behavior. In particular, tested JDBC drivers behave differently when the database is shut down while an application is running. Always avoid abruptly shutting down a database while there are applications holding open connections to it.

Oracle 8.1.7
Calling the JDBC Connection.close() method after MQQueueManager.disconnect() generates an SQLException. Either call Connection.close() before MQQueueManager.disconnect(), or omit the call to Connection.close().

DB2(R)
Sometimes DB2 returns a SQL0805N error. This problem can be resolved with the following CLP command:
  DB2 bind @db2cli.lst blocking all grant public

Refer to the DB2 documentation for more information.

Solaris and JDK 1.3
When running on Solaris with JDK 1.3, attempting to start the queue manager from a user ID other than root or mqm is likely to fail to load the jdbcora switch file with the following message being put to the error log:
AMQ6175: The system could not dynamically load the library /opt/mqm/java/lib/jdbcora.
The error message was ld.so.1: amqzxma0: fatal: libverify.so: open failed:
No such file or directory. The Queue Manager will continue without this module.

The problem arises because of a dependency between two libraries in JDK1.3 that cannot be resolved by the dynamic linker when the invoking program has the setuid bit set (as strmqm does).

Under these circumstances, start the queue manager from the mqm user ID; if this is not practical, make a symbolic link for libverify into /usr/lib. For example:

  ln -s /usr/j2se/jre/lib/sparc/libverify.so /usr/lib/libverify.so

Solaris and multiple XAResourceManager stanzas
When attempting to use multiple XAResourceManager stanzas on any given queue manager on Solaris, the commit call might fail. Treat this as an unsupported combination; it does not affect queue managers with a single XAResourceManager stanza.

Windows systems

The JDBC libraries supplied with WebSphere MQ Java (jdbcdb2.dll and jdbcora.dll) have a dependency on jvm.dll, which is supplied with the JVM. However, depending on the JVM used, this DLL might be in a subdirectory that is not on the path; for example, jre/bin/classic/jvm.dll.

If jvm.dll cannot be found when the queue manager starts, the queue manager produces a message like the following (this example is for DB2):

AMQ6174: The library C:\Program Files\IBM\MQSeries\Java\lib\jdbc\jdbcdb2.dll
was not found. The queue manager will continue without this module.

In fact, the file not found is jvm.dll. The solution is to either copy jvm.dll to somewhere already on the path or update the path to include the location of jvm.dll.

 

WebSphere is a trademark of the IBM Corporation in the United States, other countries, or both.

 

IBM is a trademark of the IBM Corporation in the United States, other countries, or both.