Not cleaned up commons pool's evictor task when SQLException occurs after the 
GenericObjectPool is initialized in createDataSource.
-----------------------------------------------------------------------------------------------------------------------------------

                 Key: DBCP-342
                 URL: https://issues.apache.org/jira/browse/DBCP-342
             Project: Commons Dbcp
          Issue Type: Bug
    Affects Versions: 1.4
         Environment: * commons-pool : 1.4
* commons-dbcp : 1.4, 1.3 both
* dbms : MSSQL 2007
            Reporter: byungchol.kim
             Fix For: 1.4.1


JIRA DBCP-93 bts is not fixed correctly
(JIRA DBCP-93 : If SQLException occurs after the GenericObjectPool is 
initialized in createDataSource, the evictor task is not cleaned up)

Only one evictor timer thread leaves but evictor timer task queued as many as 
createDataSource() method called.
queued evictor will keep tries to make connection to meet min idle connection.
if suddenly dbms become stable and can accept connection again,
then every queued evictor will try to make connection simultaneously.

In my case there were more then 100000 user requests while I set wrong password 
to database,
when I change my password to correct in database 
more then 100000 evictor tries to make connection
and finally mssql makes connections as many as integer limit and dbms dies.

here is my test.

{code:title=TestBasicDataSource.java}
    public void testCreateDataSourceCleanupEvictor() throws Exception {
        ds.close();
        ds = null;
        ds = createDataSource();
        
ds.setDriverClassName("org.apache.commons.dbcp.TesterConnRequestCountDriver");
        ds.setUrl("jdbc:apache:commons:testerConnRequestCountDriver");
        ds.setValidationQuery("SELECT DUMMY FROM DUAL");
        ds.setUsername("username");
        
        // Make password incorrect, so createDataSource will throw
        ds.setPassword("wrong");
        // Set timeBetweenEvictionRuns > 0, so evictor will be created
        ds.setTimeBetweenEvictionRunsMillis(100);
        // Set min idle > 0, so evictor will try to make connection as many as 
idle count
        ds.setMinIdle(2);
        
        Class.forName("org.apache.commons.dbcp.TesterConnRequestCountDriver");
        TesterConnRequestCountDriver testerDriver = 
(TesterConnRequestCountDriver) 
DriverManager.getDriver("jdbc:apache:commons:testerConnRequestCountDriver");
        testerDriver.initConnRequestCount();
        
        // user request 10 times
        for (int i=0; i<10; i++) {
                try {
                        @SuppressWarnings("unused")
                                DataSource ds2 = ds.createDataSource();
                } catch (SQLException e) {
                        // Ignore
                }
        }

        // sleep 1000ms. evictory will invoked 10 times.
        Thread.sleep(1000);
        
        // if orphan evictor is alive, connection request count will be 100 
which is denoted from (ds.createDataSource() count * evictor invoke count)
        // if DBMS connection is back to stable in 10 minutes then this test 
case will make 120000 connections simultaneously
        //              120000 connections = ds.createDataSource() count (10) * 
evictor invoke count (6000) * min idle (2)
        // but if evictor is cleaned up, connection request count will be only 
10 (ds.createDataSource() count )
        assertEquals(10, testerDriver.getConnectionRequestCount());
        
        // fail to create datasource then clean up orphan connection pool and 
evictor in connnection pool
        assertNull(ds.connectionPool);
    }
}
{code}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to