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