You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Meikel Bisping <M....@gmx.de> on 2005/01/27 10:14:45 UTC
[dbcp] patch suggestion for invalidate Connection
I had some problems with the invalidateObject function and suggest a
patch.
When I use
PoolingDriver driver = (PoolingDriver)
DriverManager.getDriver("jdbc:apache:commons:dbcp:");
driver.getConnectionPool("mypool").invalidateObject(con);
The connection isn't really closed because internally
PoolableConnectionFactory.destroyObject only closes
PoolableConnections.
The connection I got, however, is a
PoolDriver.PoolGuardConnectionWrapper which extends
DelegatingConnection (but not PoolableConnection).
You can test this with code like this:
String poolname="example";
int maxConn=10;
Connection
con=DriverManager.getConnection("jdbc:apache:commons:dbcp:" +
poolname);
Statement stm=con.createStatement();
stm.execute("create temp table tmp_dummy(col1 integer)");
stm.close();
System.out.println(" con :"+con);
//something goes wrong so we have to invalidate the Connection
PoolingDriver driver = (PoolingDriver) DriverManager
.getDriver("jdbc:apache:commons:dbcp:");
driver.getConnectionPool(poolname).invalidateObject(con);
for(int i=0;i<maxConn;i++)
{
Connection
con2=DriverManager.getConnection("jdbc:apache:commons:dbcp:" +
poolname);
System.out.println("trying con "+i+" :"+con2);
Statement stm2=con2.createStatement();
stm2.execute("create temp table tmp_dummy(col1 integer)");
stm2.close();
}
The invalidated connection wasn't really closed and a validation
query might still work. The problem becomes clear when the temp table
already exists.
By adding the following patch to
PoolableConnectionFactory I got invalidateObject to work properly.
public void destroyObject(Object obj) throws Exception {
if(obj instanceof PoolableConnection) {
((PoolableConnection)obj).reallyClose();
}
//begin patch invalidateConnections
else
if (obj instanceof DelegatingConnection)
{
DelegatingConnection con=(DelegatingConnection)obj;
boolean
rememberState=PoolingDriver.isAccessToUnderlyingConnectionAllowed();
PoolingDriver.setAccessToUnderlyingConnectionAllowed(true);
if (con.getDelegate()!=null&&con.getDelegate() instanceof
PoolableConnection)
{
((PoolableConnection)con.getDelegate()).reallyClose();
}
PoolingDriver.setAccessToUnderlyingConnectionAllowed(rememberState);
}
//end patch invalidateConnections
}
Regards,
Meikel Bisping
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: [dbcp] patch suggestion for invalidate Connection
Posted by Dirk Verbeeck <di...@pandora.be>.
I don't like the new dependency PoolableConnectionFactory -> PoolingDriver
Lets add this method to PoolingDriver (and add reference to pool to
wrapper)
public void invalidateConnection(Connection conn) throws
SQLException {
if (conn instanceof PoolGuardConnectionWrapper) { // normal case
PoolGuardConnectionWrapper pgconn =
(PoolGuardConnectionWrapper) conn;
ObjectPool pool = pgconn.pool;
Connection delegate = pgconn.delegate;
try {
pool.invalidateObject(delegate);
}
catch (Exception e) {
}
pgconn.delegate = null;
}
else {
throw new SQLException("Invalid connection class");
}
}
Full source here:
http://cvs.apache.org/~dirkv/PoolingDriver.java
Is this ok for you?
-- Dirk
Meikel Bisping wrote:
> I had some problems with the invalidateObject function and suggest a
> patch.
>
> When I use
> PoolingDriver driver = (PoolingDriver)
> DriverManager.getDriver("jdbc:apache:commons:dbcp:");
> driver.getConnectionPool("mypool").invalidateObject(con);
>
> The connection isn't really closed because internally
> PoolableConnectionFactory.destroyObject only closes
> PoolableConnections.
> The connection I got, however, is a
> PoolDriver.PoolGuardConnectionWrapper which extends
> DelegatingConnection (but not PoolableConnection).
>
> You can test this with code like this:
>
> String poolname="example";
> int maxConn=10;
> Connection
> con=DriverManager.getConnection("jdbc:apache:commons:dbcp:" +
> poolname);
> Statement stm=con.createStatement();
> stm.execute("create temp table tmp_dummy(col1 integer)");
> stm.close();
> System.out.println(" con :"+con);
> //something goes wrong so we have to invalidate the Connection
>
> PoolingDriver driver = (PoolingDriver) DriverManager
> .getDriver("jdbc:apache:commons:dbcp:");
> driver.getConnectionPool(poolname).invalidateObject(con);
>
> for(int i=0;i<maxConn;i++)
> {
> Connection
> con2=DriverManager.getConnection("jdbc:apache:commons:dbcp:" +
> poolname);
> System.out.println("trying con "+i+" :"+con2);
> Statement stm2=con2.createStatement();
> stm2.execute("create temp table tmp_dummy(col1 integer)");
> stm2.close();
> }
>
> The invalidated connection wasn't really closed and a validation
> query might still work. The problem becomes clear when the temp table
> already exists.
>
> By adding the following patch to
> PoolableConnectionFactory I got invalidateObject to work properly.
>
> public void destroyObject(Object obj) throws Exception {
> if(obj instanceof PoolableConnection) {
> ((PoolableConnection)obj).reallyClose();
> }
> //begin patch invalidateConnections
> else
> if (obj instanceof DelegatingConnection)
> {
> DelegatingConnection con=(DelegatingConnection)obj;
> boolean
> rememberState=PoolingDriver.isAccessToUnderlyingConnectionAllowed();
> PoolingDriver.setAccessToUnderlyingConnectionAllowed(true);
> if (con.getDelegate()!=null&&con.getDelegate() instanceof
> PoolableConnection)
> {
> ((PoolableConnection)con.getDelegate()).reallyClose();
> }
>
> PoolingDriver.setAccessToUnderlyingConnectionAllowed(rememberState);
> }
> //end patch invalidateConnections
> }
>
> Regards,
>
> Meikel Bisping
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org