Bug #30990 | JDBC connections do not properly free up resources when returned a pool | ||
---|---|---|---|
Submitted: | 13 Sep 2007 4:30 | Modified: | 16 Nov 2007 20:35 |
Reporter: | Nathan McEachen | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / J | Severity: | S3 (Non-critical) |
Version: | connectorJ 5.0.4 & 5.0.7 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | ConnectionPool, connectorj, jdbc |
[13 Sep 2007 4:30]
Nathan McEachen
[13 Sep 2007 13:15]
Mark Matthews
If you're using a connection pool that _doesn't_ use the ConnectionPoolDataSource API to create connections that have lifecycle callbacks, then it is the _pool's_ responsibility to cleanup "logical" pooled connections when they're returned to the pool. Otherwise there is no way for a JDBC driver to tell that a connection is being pooled "above" it, and thus no event/method call where one can hook in to determine that you've been "logically" closed and returned to the pool. You don't state which version of DBCP you're using, but more recent ones automatically call rollback() on connections that are returned to the pool. You can see whether this is happening or not by looking at MySQL's "general" query log on the mysql server side of things, or by adding "profileSQL=true" to your JDBC URL configuration properties. (I know that DBCP 1.2.1, a somewhat older release does take care of sending rollback() on connections returned to a pool, we use it internally in our monitoring application, so I've been through the code quite q bit). Would it be possible to get this information from you? If you can show us that for your case, Connector/J is flowing a commit() or rollback() to the database for _both_ the DML and DDL connections, then this is more than likely a MySQL server bug, since the only "lock release" mechanisms a client has at a transactional level is sending "commit" or "rollback" to the server.
[21 Sep 2007 15:59]
Nathan McEachen
profileSql=true
Attachment: log.txt (text/plain), 12.04 KiB.
[21 Sep 2007 16:00]
Nathan McEachen
Mark, Thanks for the very fast response. I will just post here instead of the bug forum until it is confirmed this is a bug or not. I am sorry for not providing you with more specifics on the DBCP I am using. I am using the Apache SharedPoolDataSoure: MysqlDataSource mysqlDataSource = new MysqlConnectionPoolDataSource(); String url = "jdbc:mysql://" + vendorProps.getString(this.serverName) + ":" + portNumber + "/"+ vendorProps.getString(this.databaseName) + "?useServerPrepStmts=false"; mysqlDataSource.setURL(url); mysqlDataSource.setUser(vendorProps.getString(this.user)); mysqlDataSource.setPassword(vendorProps.getString(this.password)); SharedPoolDataSource sharedPoolDataSource = new SharedPoolDataSource(); sharedPoolDataSource .setConnectionPoolDataSource((MysqlConnectionPoolDataSource) mysqlDataSource); sharedPoolDataSource.setMaxActive(this.maxDbConnections); I explicitly perform a commit or a rollback on the connection object before I return it to the pool. I would think regardless as to whether the DBCP called commit or rollback, I should be OK. Thanks for your time looking into this! I attached a file containing the output by setting profileSql to true.
[16 Nov 2007 17:13]
Nathan McEachen
PING! Hey, thanks for looking into this issue. Any ideas? I am willing to also discuss this off line, even over the phone.
[16 Nov 2007 20:35]
Nathan McEachen
Hey, I discovered that the problem is on my end. I have aspects loaded at runtime that were interfering with the internals of com.mysql.jdbc.Connection. The reason it was working with the other databases is because I was explicitly excluding their packages from load time weaving. Once I explicitly excluded the "com.mysql" package, everything worked fine. More specifically, it looks like my Aspect was bypassing an internal call to rollback on Connection. Sorry for suggesting this might be a bug. Thanks for your time. -Nathan