Caldarale, Charles R wrote:
From: André Warnier [mailto:[EMAIL PROTECTED]
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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to