Philip, On 8/18/15 11:42 AM, Wernersbach, Philip wrote: > Christopher, > > On 8/17/15, 5:59 PM, "Christopher Schultz" <ch...@christopherschultz.net> > wrote: > >> Philip, >> >> On 8/17/15 12:27 PM, Wernersbach, Philip wrote: >>> We are developing a JDBC driver that implements the JDBC API. Our >>> driver works and we can use it in servlets, but Tomcat doesn¹t seem >>> to know that the connections in the thread pool can be reused, so >>> after all of the connection slots in the thread pool are used, the >>> servlets hang trying to get a connection. >> >> If you set maxTotal="1", you get a timeout when you try to fetch a >> second connection? > > Yes. To test this I modified the code and got two connections > consecutively, and it hung on getting the second connection.
Did you return the first one before requesting a second one? >> Are you sure the servlet called Connection.close()? > > That seemed to be the problem. I audited our code and found a corner case > where Connection.close() was not called. I fixed it, and all seems to work > as it should. Good. >> What does the stack trace of the request-processing thread look like >> when it's hung up? > > It hung at DataSource.getConnection() with this stack trace: > > Unsafe.park(boolean, long) line: not available [native method] > LockSupport.park(Object) line: 175 > AbstractQueuedSynchronizer$ConditionObject.await() line: 2039 > LinkedBlockingDeque<E>.takeFirst() line: 582 > GenericObjectPool<T>.borrowObject(long) line: 439 > GenericObjectPool<T>.borrowObject() line: 360 > PoolingDataSource<C>.getConnection() line: 133 > BasicDataSource.getConnection() line: 1532 > IngDb.getDbConnection() line: 42 I think this is expected behavior; when all the connections are checked-out, client code has to wait for a connection to be returned, or for the pool to consider the connection to be "abandoned", evict the abandoned connection from the pool, and create a new connection (which can then be given-out to clients). >>> What API does the Tomcat DataSource Connection thread pool use to >>> know a connection can be reused? This is an API question, but our >>> specific version of Tomcat is 8.0.24. >> >> Are you using DBCP2 (the default) or Tomcat's jdbc-pool? > > DBCP2 > >> >> Do you mean to check to see if a connection is valid for re-use? > > Our servlet code doesn¹t need to check if a connection is valid for > re-use, we just need Tomcat to know that our connections are always valid > for re-use in the pool (the database connection is automatically kept > alive until it is explicitly closed). > >> >> I think the answer for /both/ is that they use this call: >> >> Connection.isValid(int timeout) >> >> What version of JDBC are you implementing? It seems that Java 6 is when >> the Connection.isValid method was added. > > JDBC 4.2, which does have Connection.isValid(), we¹ve implemented it. > >> >> Or did you mean to check to see if a connection can be re-used *at all* >> -- meaning, can the connection even really be used in a pool? >> >> What does your <Resource> element look like in context.xml? >> >> -chris > > I¹m assuming Tomcat will automatically take care of pooling even though > we¹re calling Connection.close()? Our close() implementation explicitly > closes the database connection, in such a way that it can¹t be reused. When client code calls Connection.close(), they are calling close() on a wrapper object. Your code won't see these close() calls because the pooled connections will intercept them and the connections will be returned to the pool. If/when the pool is shut-down, your Connection objects should see a .close() call. I'm concerned about your lack of understanding of the way a connection pool works and inability to debug it sufficiently before asking in this forum, if you are to be implementing a JDBC driver. :/ -chris
signature.asc
Description: OpenPGP digital signature