0 Replies Latest reply on Dec 18, 2009 3:01 PM by domsparks

    With Oracle JDBC, JDBCConnection is being closed erroneously following an IllegalArgumentException. This causes other, unrelated, transaction to fail

    domsparks

      HI,

       

      not sure if this is a bug, but it seems wrong to me.

       

      Basically the scenario is this.

      I have a SessionEJB (EJB1) with Container Manager Transactions.

      It has a method 'execute' which is marked as RequiresNew.

      Within the execute() method it invokes a method on another SessionEJB (EJB2), which results in a new transaction (cos it's also 'RequiresNew')

      I can execute code that causes the Oracle JDBC driver to throw an IllegalArgumentException.  Following this, not only is the transaction on EJB2 rolled back, but often (not always) I get problems later, because the underlying jdbc connection has been closed.

       

      The behaviour (deep within the code that is failing) is similar to what's described in this (fixed) issue: https://jira.jboss.org/jira/browse/JBAS-5678

       

      Here's some pseudocode that illustrates it.

      In my class EJB1 (a stateless SessionBean):

       

       

      //EJB1 has Container managed transactions

      //this method defined with ‘RequiresNew’

       

      public void execute() {

       

                      doSomeStuffOnDatabase();

       

                      try {

                          EJB2.executeNew();       //EJB2 has Container Managed Trans, and this method is ‘RequiresNew’

                          } catch (throwable th) {

                           //log-it

                      }

       

                      doOtherStuffOnDatabase();

      }

       

      So basically:

         I have a transaction for the EJB1.execute() method.  It does some database stuff, so is using a JDBC connection to Oracle (Obtained from the jboss connection pool using standard J2EE datasources etc).

         When EJB2.executeNew() is entered, the outer-scope’s transaction is suspended. EJB2.executeNew() executes and it’s transaction is usually committed/rolled back correctly. Note that even in the case where failure occurs, executeNew() is internally handling all throwables, so no Throwables are actually propagated into the outer execute() method.

       

          Outer scope transaction resumes, and then doOtherStuffOnDatabase completes using that transaction (and whatever JDBC Connection(s) it has acquired).

       

      The problem I have has some similarities to JBAS-5678. 

      Within the executeNew() method, I can easily get Oracle JDBC drivers (ojdbc14.jar) to throw an IllegalArgumentException rather than a SQLException. (Basically doing rs.getTimestamp(x), where column x is not a timestamp, will generate the error). [and before anyone suggests it, I can't necessarily always prevent this occurring, because in our product the SQL and the code that handles the result set are dynamically created and can legitimately be erroneous without it being considered a bug in our product]

       

      The problem I have in this case is that often (but not always), the outer-scope’s transaction & jdbc connection is affected by the failure of the transaction in EJB2.executeNew().  I get errors because the JDBC connection has been closed.

      I don’t pretend to understand anything about how the underlying JDBC connections are used within the transactions, but I’m fairly sure that the two transactions are supposed to be entirely unrelated; the outer-one is suspended during the execution of the inner one, and should succeed or fail independently of the outcome of the inner one (provided the error handling is as above; all Throwables thrown when invoking EJB2.executeNew() are handled).  It also works entirely correctly in the case of SQLExceptions as opposed to IllegalArgumentExceptions.

       

      My guess is that the various classes handling/wrapping the oracle jdbcConnection, are not correctly handling the case of Throwables that are not SQLExceptions. I'd guess they are simply closing the connection (after rolling back, as per bug JBAS-5678), regardless of whether the connection is in use by any other transactions (that should complete normally).

       

       

      I also don’t know why the jdbc connection would get closed; after all, an IllegalArgumentException is not an unrecoverable error, and is not cause for rolling back a transaction (I don’t know whether it actually does get rolled back at this point, but I'd guess so); it would be perfectly legit for my code to handle such an exception and still carry on obtaining results from my resultSet, etc.

       

      Can anyone confirm that I'm not going crazy, and that the above is actually incorrect behaviour?  I'm 100% sure that the transactions are established, suspended, resumed,etc correctly; it's just that this jdbc connection seems to be (sometimes) used by both transactions, even though they unrelated, and hence it's closure in one transaction is breaking the other.

       

       

      Thanks,