3 Replies Latest reply on Mar 5, 2006 10:31 PM by Blaine Simpson

    help getting new HSQLDB XA DataSource working

    Blaine Simpson Newbie

      I'm a developer in the HSQLDB Development Group. An associate and I have
      made an XADataSource according to the javax.sql API spec and chapters 11
      and 12 of the JDBC 3.0 Spec, but it is not working with JBoss. I have put
      a lot of work into this, and I would greatly appreciate any advice or
      assistance to help get it working.
      According to the JBoss JCA FAQ, JBoss should drive "custom/thirdparty"
      XADataSources "using the standard api". But the pooling callback mechanism
      isn't working. I see that JBoss registers its ConnectionEventListeners as
      it should, but it is impossible for my JDBC Driver's Connection
      implementation to do its part, because
      org.jboss.resource.adapter.jdbc.WrappedConnection seems to intercept
      end-user calls to close(). My problems are specifically with javax.sql
      pooling, not with XA-related classes, but if I understand the docs, JBoss
      does not support straight javax.sql pooling other than through the
      XAConnection subinterface. It would be great if I could work on the
      PooledConnection problems directly without the unnecessary complexity of
      global transactions.

      Quoting the relevant statements from the JDBC spec:

      The driver invokes the ConnectionEventListener methods
      connectionClosed and connectionErrorOccurred when the corresponding
      events occur. [Impossible for me to do if my driver's
      Connection.close() is never invoked.]

      The application server calls the method
      PooledConnection.getConnection to get a logical Connection object...
      The logical Connection object is returned to the JDBC client.
      [JBoss is not returning my logical Connection object to the JDBC
      client, but it's own WrappedConnection].

      Here is exactly what I see:

      In a JSP page, I get a UserTransaction from JNDI, get a Connection
      from my XADataSource, execute some SQL, commit ut, close connection;
      repeat. The connections are ConnectionWrappers holding Connection
      instances from my driver. The Connections are "pooled" in that my
      second getConnection reuses the physical connection from the first--
      but the connection is not reset in between as it should be, because
      my driver was never informed about the JSP's Connection.close().
      The second JDBC session is the same as if I had continued to use
      the original connection, instead of closing and re-opening (a bad
      thing since Schemas and various back end resources need to be reset).

      I then bypassed your ConnectionWrapper's interception of
      Connection.close() by extracting my "logical Connection" from your
      wrapper and invoking close() on that (as the JDBC spec says to do in
      the second quote above). My JDBC driver then invokes your
      connection manager's connectionClosed() method, as it should. But
      your connection manager does no pooling in this case. According to
      the JDBC Spec, the connection manager uses connectionClosed() to
      find out that a LOGICAL connection is closed and then should use
      its pooling algorithm to determine whether to reuse a connection or
      get another physical connection from the ConnectionPoolDataSource or
      XADataSource. Again, from the JDBC 3.0 Spec:

      When the JDBC application closes its logical connection, the
      JDBC driver notifies the connection pool manager (the listener)
      by calling the listener's implementation of the method
      connectionClosed. At htis point, the connection pool manager
      can return the PooledConnection object to the pool for reuse.

      but no connections are ever reused. Every time I run this modified
      JSP (which avoids ConnectionWrapper's close() interceptions), your
      connection manager requests two additional XA/PooledConnections
      (which correspond to physical connections).