Author: psteitz Date: Wed Feb 4 13:42:53 2015 New Revision: 1657221 URL: http://svn.apache.org/r1657221 Log: Made sure BasicDataSource createDataSource fully initializes instance. JIRA: DBCP-432.
Modified: commons/proper/dbcp/trunk/src/changes/changes.xml commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java Modified: commons/proper/dbcp/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/changes/changes.xml?rev=1657221&r1=1657220&r2=1657221&view=diff ============================================================================== --- commons/proper/dbcp/trunk/src/changes/changes.xml (original) +++ commons/proper/dbcp/trunk/src/changes/changes.xml Wed Feb 4 13:42:53 2015 @@ -98,7 +98,11 @@ The <action> type attribute can be add,u Added fastFailValidation property to PooloableConnection, configurable in BasicDataSource. When set to true, connections that have previously thrown fatal disconnection errors will fail validation immediately (no driver calls). - </action> + </action> + <action issue="DBCP-432" dev="psteitz" type="fix"> + Changed BasicDataSource createDataSource method to ensure that initialization + completes before clients get reference to newly created instances. + </action> </release> <release version="2.0.1" date="24 May 2014" description="This is a bug fix release."> <action dev="markt" type="fix"> Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java?rev=1657221&r1=1657220&r2=1657221&view=diff ============================================================================== --- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java (original) +++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java Wed Feb 4 13:42:53 2015 @@ -2080,10 +2080,11 @@ public class BasicDataSource implements } // Create the pooling data source to manage connections + DataSource newDataSource; success = false; try { - dataSource = createDataSourceInstance(); - dataSource.setLogWriter(logWriter); + newDataSource = createDataSourceInstance(); + newDataSource.setLogWriter(logWriter); success = true; } catch (SQLException se) { throw se; @@ -2110,6 +2111,7 @@ public class BasicDataSource implements // If timeBetweenEvictionRunsMillis > 0, start the pool's evictor task startPoolMaintenance(); + dataSource = newDataSource; return dataSource; } } Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java?rev=1657221&r1=1657220&r2=1657221&view=diff ============================================================================== --- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java (original) +++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/TestBasicDataSource.java Wed Feb 4 13:42:53 2015 @@ -682,6 +682,32 @@ public class TestBasicDataSource extends StackMessageLog.unLock(); } } + + @Test + public void testConcurrentInitBorrow() throws Exception { + ds.setDriverClassName("org.apache.commons.dbcp2.TesterConnectionDelayDriver"); + ds.setUrl("jdbc:apache:commons:testerConnectionDelayDriver:50"); + ds.setInitialSize(8); + + // Launch a request to trigger pool initialization + TestThread testThread = new TestThread(1,0); + Thread t = new Thread(testThread); + t.start(); + + // Get another connection (should wait for pool init) + Thread.sleep(100); // Make sure t gets into init first + ds.getConnection(); + + // Pool should have at least 6 idle connections now + // Use underlying pool getNumIdle to avoid waiting for ds lock + assertTrue(ds.getConnectionPool().getNumIdle() > 5); + + // Make sure t completes successfully + t.join(); + assertFalse(testThread.failed()); + + ds.close(); + } } /** @@ -710,3 +736,28 @@ class TesterConnRequestCountDriver exten connectionRequestCount.set(0); } } + +/** + * TesterDriver that adds latency to connection requests. Latency (in ms) is the + * last component of the URL. + */ +class TesterConnectionDelayDriver extends TesterDriver { + private static final String CONNECT_STRING = "jdbc:apache:commons:testerConnectionDelayDriver"; + + @Override + public Connection connect(String url, Properties info) throws SQLException { + String[] parsedUrl = url.split(":"); + int delay = Integer.parseInt(parsedUrl[parsedUrl.length - 1]); + try { + Thread.sleep(delay); + } catch(InterruptedException ex) { + Thread.currentThread().interrupt(); + } + return super.connect(url, info); + } + + @Override + public boolean acceptsURL(String url) throws SQLException { + return url.startsWith(CONNECT_STRING); + } +}