[ 
https://issues.apache.org/jira/browse/DBCP-443?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14988171#comment-14988171
 ] 

Justin Cranford commented on DBCP-443:
--------------------------------------

I found a workaround. I am not sure it points to an issue with DBCP or not.

For background, my JDBC stack is: DBCP 2.1 BasicDataSource -> HA-JDBC 3.0.4 
DataSource -> MySQL Connector/J 5.1.31

- DBCP2 BasicDataSource config -> Tomcat server.xml (without 
connectionProperties)
- HA-JDBC DataSource config -> ha-jdbc-mycluster.xml (with connectionProperties)

To workaround the issue with DBCP2 evictor thread not getting 
connectionProperties, I copied the connectionProperties from my HA-JDBC 
DataSource config to my DBCP2 BasicDataSource config. After that, DBCP2 evictor 
thread gets the connectionProperties.


I am not sure if this is expected behaviour for DBCP2 or not. I assumed DBCP2 
BasicDataSource used a delegate pattern for all internal JDBC calls (ex: 
evictor thread) go whatever DataSource object is wraps (ex: a HA-JDBC 
DataSource instance). That is not the case, though. It seems to be doing 
delegate calls to a wrapped DataSource instance, but mixing in Driver.connect() 
calls which are not connected to the delegate DataSource object. By doing 
Driver.connect() calls, it is establishing new connections and explicitly 
passing its own connectionProperties instead of reusing what the DataSource 
already has.

Anyway, I have a workaround. I thought I would let you know so you can decide 
if this is a DBCP2 issue or not.

> Evictor thread not passing DBCP connectionProperties to Driver.connect()
> ------------------------------------------------------------------------
>
>                 Key: DBCP-443
>                 URL: https://issues.apache.org/jira/browse/DBCP-443
>             Project: Commons Dbcp
>          Issue Type: Bug
>    Affects Versions: 1.3
>         Environment: Tomcat 5.5.31 (bundles DBCP 1.3.0 and Pool 1.5.4)
> MySQL Connector/J 5.1.31
> MySQL 5.1
>            Reporter: Justin Cranford
>
> DBCP 1.3.0 is passing connectionProperties to Driver.connect() when called 
> during borrow, but not when called by the evictor thread. This is a problem 
> when using DBCP with Connector/J because that MySQL JDBC driver defaults to 
> connectTimeout=0 (indefinite hang). I am setting connectTimeout=10000 in my 
> DBCP <Resource> connectionProperties to explicitly avoid this issue, but DBCP 
> is not always using it in Driver.connect() calls.
> I did not see this issue in DBCP change log 
> (http://commons.apache.org/proper/commons-dbcp/changes-report.html) so I am 
> reporting it. I am wondering if this also affects DBCP 1.4/2.x for Java 6/7 
> respectively, but I don't have an environment to test that.
> Here is the stack being used:
>         Tomcat 5.5.31 ===> DBCP 1.3.0 (w/ Pool 1.5.4) ===> HA-JDBC 2.0.15 
> ===> Connector/J 5.1.31
> For background, HA-JDBC is a JDBC proxy connection. It does two-phase to two 
> underlying Connector/J databases defined in a separate config file. However, 
> the issue has nothing to do with HA-JDBC.
> The issue is right at the DBCP entry point into Driver.connect(). In my case, 
> that Driver.connect() call is into HA-JDBC, and it passes any connection 
> properties down to each Connector/J Driver.connect() call.
> I put a debug on the first line of HA-JDBC's Driver.connect() to confirm this 
> issue. I logged a stack trace with the value of connectTimeout passed in from 
> DBCP. For DBCP borrow stack traces, I see connectTimeout=10000. For DBCP 
> evictor stack traces, I see connectTimeot=null. For example:
>         java.lang.Exception: Driver.connect url=jdbc:ha-jdbc:cspm_mysql 
> connectTimeout=null
>                 at net.sf.hajdbc.sql.Driver.connect(Driver.java:86)
>                 at 
> org.apache.tomcat.dbcp.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)
>                 at 
> org.apache.tomcat.dbcp.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582)
>                 at 
> org.apache.tomcat.dbcp.pool.impl.GenericObjectPool.addObject(GenericObjectPool.java:1617)
>                 at 
> org.apache.tomcat.dbcp.pool.impl.GenericObjectPool.ensureMinIdle(GenericObjectPool.java:1575)
>                 at 
> org.apache.tomcat.dbcp.pool.impl.GenericObjectPool.access$700(GenericObjectPool.java:190)
>                 at 
> org.apache.tomcat.dbcp.pool.impl.GenericObjectPool$Evictor.run(GenericObjectPool.java:1709)
>                 at java.util.TimerThread.mainLoop(Unknown Source)
>                 at java.util.TimerThread.run(Unknown Source)
> If I am defining DBCP connectionProperties, I would expect DBCP to pass those 
> properties to all calls of Driver.connect(). I see a Properties object is 
> passed in the evictor thread, but it does not seem to be initialized 
> properly. I am not sure how to trace that back to BasicDataSource, though.
> Here is my DBCP <Resource>. You can see my connectionProperties for HA-JDBC 
> includes connectTimeout=10000.
>             <Resource name="jdbc/mydb" auth="Container" 
> type="javax.sql.DataSource"
>               maxActive="100" maxIdle="25" minIdle="5"
>               removeAbandoned="true" removeAbandonedTimeout="28800" 
> logAbandoned="true"
>               validationQueryTimeout="15" validationQuery="/* ping */ SELECT 
> 1 FOR UPDATE"
>               testOnBorrow="true" testOnReturn="false" maxWait="15000"
>               testWhileIdle="false" timeBetweenEvictionRunsMillis="900000" 
> numTestsPerEvictionRun="10" minEvictableIdleTimeMillis="1800000"
>               username="mydbpublic" password="mydbpwd"
>               driverClassName="net.sf.hajdbc.sql.Driver" 
> url="jdbc:ha-jdbc:mysql"
>               
> connectionProperties="connectTimeout=10000;socketTimeout=20000;useUnicode=true;characterSetResults=utf8;cacheServerConfiguration=true;alwaysSendSetIsolation=false;useLocalSessionState=true;useLocalTransactionState=true;useHostsInPrivileges=false;enableQueryTimeouts=true;maintainTimeStats=false;maxAllowedPacket=-1;"/>
> Another consequence of this issue is Commons Pool 1.5.4 uses a TimerTask for 
> the evictor thread. TimerTask does not wait for previous iterations to 
> complete. If the evictor timer runs frequenctly, this issue could accumulate 
> socket and file descriptor resources for hung Connector/J connections. Maybe 
> that is not a problem for DBCP -> Connector/J setups, but it is for DBCP -> 
> HA-JDBC -> Connector/J stacks where HA-JDBC attempts to connect to both but 
> only needs one of the underlying databases to connect while the other hangs.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to