Known problems and limitations with JTA/JDBC coordination

Some of the problems and limitations of JTA/JDBC support depend on the database management system in use, for example, tested JDBC drivers behave differently when the database is shut down while an application is running. If the connection to the database that an application is using is broken, there are steps that the application can perform to reestablish a new connection to the queue manager and the database so that it can then use those new connections to perform the transactional work required.

Because the JTA/JDBC support makes calls to JDBC drivers, the implementation of those JDBC drivers can have a significant effect on the system behavior. In particular, tested JDBC drivers behave differently when the database is shut down while an application is running.

Important: Always avoid abruptly shutting down a database while there are applications that are holding open connections to it. Note: An IBM MQ classes for Java application must connect by using bindings mode to make IBM MQ act as a database coordinator.

    Multiple XAResourceManager stanzas
    The use of more than one XAResourceManager stanza in a queue manager configuration file, qm.ini, is not supported. Any XAResourceManager stanza other than the first is ignored.

    Db2®
    Sometimes Db2 returns a SQL0805N error. This problem can be resolved with the following CLP command:
    DB2 bind @db2cli.lst blocking all grant public
    
    For more information, refer to the Db2 documentation. The XAResourceManager stanza must be configured to use ThreadOfControl=PROCESS. For Db2 Version 8.1 and higher, this does not match the default thread of control setting for Db2, so toc=p must be specified in the XA Open String. An example XAResourceManager stanza for Db2 with JTA/JDBC coordination is as follows:
    XAResourceManager:
         Name=jdbcdb2
         SwitchFile=jdbcdb2
         XAOpenString=uid=userid,db=dbalias,pwd=password,toc=p
         ThreadOfControl=PROCESS
    
    This does not prevent the Java applications that use JTA/JDBC coordination from being multithreaded themselves.

    Oracle
    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().


Handling issues with database connections

When an IBM MQ classes for Java application uses the JTA/JDBC support that is provided by IBM MQ, it typically performs the following steps:
  1. Creates a new MQQueueManager object to represent a connection to the queue manager that will act as the transaction manager.
  2. Constructs an XADataSource object that contains details about how to connect to the database that will be enlisted in the transaction.
  3. Calls the method MQQueueManager.getJDBCConnection(XADataSource) passing in the XADataSource that was created previously. This causes the IBM MQ classes for Java to establish a connection to the database.
  4. Calls the method MQQueueManager.begin() to start the XA transaction.
  5. Performs the messaging and database work.
  6. When all of the required work has been completed, calls the method MQQueueManager.commit(). This completes the XA transaction.
  7. If a new XA transaction is required at this point, the application can repeat steps 4, 5 and 6.
  8. When the application has finished, it should close the database connection that was created at step 3, and then call the method MQQueueManager.disconnect() to disconnect from the queue manager.
The IBM MQ classes for Java maintain an internal list of all of the database connections that have been created when an application calls MQQueueManager.getJDBCConnection(XADataSource). If a queue manager needs to communicate with the database during the processing of the XA transaction, the following processing takes place:
  1. The queue manager calls into the IBM MQ classes for Java, passing in details of the XA call that needs to be passed to the database.
  2. The IBM MQ classes for Java then look up the appropriate connection in the list, and then use that connection to flow the XA call to the database.
If the connection to the database is lost at any point during this processing, the application should:
  1. Back out any existing work that was done under the transaction, by calling the method MQQueueManager.backout().
  2. Close the database connection. This should cause the IBM MQ classes for Java to remove details of the broken database connection from its internal list.
  3. Disconnect from the queue manager, by calling the method MQQueueManager.disconnect().
  4. Establish a new connection to the queue manager, by constructing a new MQQueueManager object.
  5. Create a new database connection, by calling the method MQQueueManager.getJDBCConnection(XADataSource).
  6. Perform the transactional work again.
This allows the application to reestablish a new connection to the queue manager and the database, and then use those connections to perform the transactional work required.