You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by "Wernersbach, Philip" <Ph...@ingramcontent.com> on 2015/08/17 18:27:18 UTC

What API does the Tomcat DataSource Connection thread pool use to know a connection can be reused?

Hello All,

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.

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.

If this doesn’t belong in dev@tomcat.apache.org, then I apologize and please ignore. This question is half way between a regular user question and a dev question, so I sent to both lists.

Thanks,

Philip Wernersbach
Software Engineer
Ingram Content

Re: What API does the Tomcat DataSource Connection thread pool use to know a connection can be reused?

Posted by "Wernersbach, Philip" <Ph...@ingramcontent.com>.
Christopher,

On 8/18/15, 1:13 PM, "Christopher Schultz" <ch...@christopherschultz.net>
wrote:

>Did you return the first one before requesting a second one?

Not when I was reproducing the hang. I am in the real code.

>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. :/

We all have to start somewhere. It¹s working now, thanks for the help!

Sincerely,

Philip Wernersbach
Software Engineer
Ingram Content


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: What API does the Tomcat DataSource Connection thread pool use to know a connection can be reused?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
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


Re: What API does the Tomcat DataSource Connection thread pool use to know a connection can be reused?

Posted by "Wernersbach, Philip" <Ph...@ingramcontent.com>.
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.

>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.

>
>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


>
>> 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.

Thanks,

Philip Wernersbach
Software Engineer
Ingram Content


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: What API does the Tomcat DataSource Connection thread pool use to know a connection can be reused?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
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? Are you sure the servlet called Connection.close()?

What does the stack trace of the request-processing thread look like
when it's hung up?

> 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?

Do you mean to check to see if a connection is valid for re-use?

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.

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


Re: What API does the Tomcat DataSource Connection thread pool use to know a connection can be reused?

Posted by Mark Thomas <ma...@apache.org>.
On 17/08/2015 17:27, Wernersbach, Philip wrote:
> Hello All,
> 
> 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.
> 
> 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.
> 
> If this doesn’t belong in dev@tomcat.apache.org, then I apologize and
> please ignore. This question is half way between a regular user
> question and a dev question, so I sent to both lists.

Best to ask on the users list first. Folks generally find dev questions
on the users list less annoying than user questions on the dev list.

I'd say this is a users question.

When the connection is closed by the application code it is returned to
the pool. (Every JDBC pool implementation will work the same way.)

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org