tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Davoust, Pascal" <pascal.davo...@eptica.com>
Subject [jdbc-pool] Transaction left open by the connection validation mechanism ?
Date Thu, 03 Jan 2013 17:49:14 GMT
Hi all,

I'm using the tomcat jdbc connection pool (7.0.34) to connect against a
PostgreSQL database (version 8.4 - jdbc driver 9.0.801) and I'm having a
potentially dodgy situation with the validation mechanism.

The code I'm using does change the transaction isolation level of a
connection that has been newly borrowed from the pool (before doing
anything else) but sometimes gets an error while doing so, such as:

org.postgresql.util.PSQLException: Cannot change transaction isolation
level in the middle of a transaction.

I've been investigating the code for a while to check whether any
transaction was left open (read: without any commit or rollback) before
being returned to the pool, but no chance, everything looks clean.

Then I suspected the validation mechanism which validates the connection.
Mine was set to validate the connection every 30 s while idle, using a
"SELECT 1" statement.

Indeed, I disabled the validation mechanism and tadaa, no error at all!

I then had a look at the corresponding code into the tomcat jdbc pool
(source 7.0.34), and more specifically in
class org.apache.tomcat.jdbc.pool.PooledConnection, method public boolean
validate(int validateAction,String sql) at line 452 (excerpt below):

        Statement stmt = null;
        try {
            stmt = connection.createStatement();
            stmt.execute(query);
            stmt.close();
            this.lastValidated = now;
            return true;
        } catch (Exception ex) {
            if (getPoolProperties().getLogValidationErrors()) {
                log.warn("SQL Validation error", ex);
            } else if (log.isDebugEnabled()) {
                log.debug("Unable to validate object:",ex);
            }
            if (stmt!=null)
                try { stmt.close();} catch (Exception ignore2){/*NOOP*/}
        }
        return false;

It looks to me that there is a mistake here: if the connection to validate
does not have autoCommit set to true, then the transaction is started and
left open by this code.
Which explains the errors I was experiencing, since once the connection has
been validated, then the transaction isolation level cannot be changed
since a transaction is still ongoing!

Did I miss something or is this a real bug which I should file?

Thanks in advance
Regards

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message