tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From André Warnier>
Subject Re: Tomcat thread pool question
Date Thu, 11 Dec 2008 00:37:38 GMT
Caldarale, Charles R wrote:
>> From: André Warnier []
>> Subject: Re: Tomcat thread pool question
>> So we have a Tomcat, which somehow has a "pool of database
>> connections" ready to be lent to webapps.
> In this particular case, the db connection pool is managed by Hibernate, not Tomcat.
 More typical usage would have Tomcat managing the pool, but it wouldn't make any difference
for this problem.
>> And we have a webapp capable of borrowing one of the
>> connections from the pool to do something with it, the
>> understanding being that when it's done, it gives it
>> back to the pool.
> That's the standard model, but this app design isn't using it.  Instead, the connections
are not returned to the pool until the client says it's ok to do so.
>> - Tomcat receives the request # 2, and passes it to the
>> same / a different thread. Say it is the same (how that
>> works I don't know, question below).
> Unlikely to be the same, but it doesn't matter.
>> - the thread somehow re-uses the same db connection which
>> was borrowed before. How ? was it saved somewhere and can
>> this thread get the same one back ?
> One presumes the webapp stored the connection somewhere retrievable, although the OP
provided no actual evidence of that.  It coule be stored in the Session, or kept in a completely
separate active connection structure managed by the webapp.
>> - Client issues HTTP request # 3, which is a signal for the webapp to
>> return the db connection to the pool
> Not just return the db connection, but also commit the db updates.
>> - Tomcat receives the request # 3, and passes it to the same / a
>> different thread. Say it is the same (how that works I don't know).
> Doesn't matter if it's the same thread or not.
>> Now my question is : considering this is HTTP, where each request is
>> supposedly independent from previous and following ones, can a scheme
>> like the above possibly work ?
> Yes, because each client can be identified by a session identifier or some other cookie.
 However, unless the client is very well controlled and extremely robust, this design abdicates
responsibility for management of server resources (the db connections) and delegated that
to the client, an extremely poor design choice.
>> Is it one particular thread which holds this borrowed db
>> connection, and is request # 2 necessarily processed by
>> the same thread as request # 1 ?
> Highly unlikely.
>> Where is the borrowed connection stored between the requests ?
> Could be in the Session object associated with the client, or some webapp-managed structure.
>> Am I right in thinking that for such a scheme to work, even
>> with well-behaved clients, the borrowed db connection would
>> need to be saved somewhere independent of a Tomcat thread,
>> but dependent on some kind of client "session", so that any
>> thread could pick it up where another one or itself left it
>> between transactions of that same client ?
> Correct; it's only a minor - albeit dangerous - variation on the frequently used shopping
cart seen on many web sites.
Thanks Chuck.

So it has nothing to do directly with the threads.
And I will suppose for now that the webapp saves each borrowed 
connection, in some place related to the session-id of the client that 
triggered the borrowing of each connection.

Suppose we have 5 available db connections in the pool, and 10 threads, 
and 15 clients.
The first 5 clients send their request # 1, resulting in 5 threads busy 
momentarily, and 5 db connections borrowed.  So the pool is empty.
The next 5 clients come in with request # 1, they also get 5 threads, 
but these threads have to wait for a db connection to become available 
in the pool again.  So these threads block, until the first client 
issues its request # 3, and one db connection is returned to the pool.
The next 5 clients arrive, and for the moment there is no thread 
available to service the request, so they block earlier, in the "accept" 
queue of the Connector or something.
So now the first client receives the response to its request # 1.
A thread is now free, and one of the waiting accept connections gets it.
This thread immediately tries to get a new db connection from the pool, 
but it cannot because it's empty. So it too has to wait, and this blocks 
another thread. So now there are 6 threads blocked.
A second client receives a response # 1 and issues a request #2. It 
doesn't get a thread, because in the meantime another waiting accept 
connection got that free thread, and also waits on a free db connection. 
So now we have 7 threads blocked, and one request # 2 waiting in the 
accept queue.
And so on.
Thus finally, if there are more threads than db connections in the pool, 
we can get completely locked up, even with clients that are perfectly 
well-behaved and always issue request # 3 if they can.
And if a client is not well-behaved and never issues its request # 3, we 
lose a db connection from the pool.
Think I got it.

But on the other hand, if you increase the number of threads above the 
number of simultaneous clients that you could possibly have, then it 
would unblock the situation, no ?
Because then each client would get a thread, and a client that issues 
request # 2 does not have to wait for a db connection, it already has 
one stored away. So it can do its thing, get its response and issue its 
request # 3, which frees a db connection.
I'm not saying that it is a good design, but maybe it's a temporary 
solution ?

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message