aspose file tools*
The moose likes JDBC and the fly likes congested webapp connection pools Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » JDBC
Bookmark "congested webapp connection pools" Watch "congested webapp connection pools" New topic
Author

congested webapp connection pools

Paul Fenerty
Greenhorn

Joined: May 06, 2005
Posts: 23
Hello,

Just ran into this:

http://www.javalobby.org/articles/thread-safe/index.jsp

... which claims that congestion in webapps results unavoidably when using tomcat's Database Connection Pooling, given synchronized access to the pooled connections:

"Having even a single synchronized block of code executed by every incoming request may bring your application to its knees with no more than 5 simultaneous users as only one thread can execute a synchronized block of code while other threads remain suspended until they can obtain a lock."

Proposed solutions to this are limited to roll-your-own ThreadLocal() code, and Spring ThreadLocal() code, that latter being the point of the article.

Thoughts on this? Really brought to one's knees with 5 users ??

The roll-your-own approach mentioned:

"Some clever people have come up with a solution by adding a filter in the servlet container configuration. Such a filter would amongst other things create a JDBC connection or Hibernate session at the start of the request before the web tier is invoked and bind it to the current thread by means of ThreadLocal for use in the business logic."

... is certainly clever, but is it not possible to gain a performance improvement more simply by wrapping connection requests in a ThreadLocal() within the DAO? something like:


===BEFORE=============================

private DataSource pool;

public void doSQLUpdate(String sqlcmd) {
Connection conn = null;
Statement stmt = null;

try {
synchronized (pool) {
conn = pool.getConnection();
}

// etc;
}

===AFTER==============================


private DataSource pool;
private static ThreadLocal cnnx = new ThreadLocal();

public Connection cnnx () {
cnnx.set( pool.getConnection() );
return (Connection)cnnx.get();
}

public void doSQLUpdate(String sqlcmd) {
Connection conn = null;
Statement stmt = null;

try {
conn = cnnx();

// etc;
}


... good idea / bad idea ??

ps: searching around for this mostly turns up ideas for rolling-your-own connection pool with ThreadLocal() ... am not interested in that ... am sticking with tomcat dbcp.

Thanks!
Paul Fenerty
Greenhorn

Joined: May 06, 2005
Posts: 23
Concurrency guru Brian Goetz thinks the ThreadLocal is a good choice for implementing per-thread-singletons, which would make for a DAO that neither clutters up the heap with per-request-objects, wastes time creating them, nor wastes time serializing requests across the bottleneck of synchronization contention.

***
good free article:
http://www.ibm.com/developerworks/java/library/j-threads3.html

***
extraordinarily insightful not-so-free-but-well-worth-it book:
http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/ref=sr_1_1/102-4676839-8071307?ie=UTF8&s=books&qid=1191445998&sr=1-1

Regarding how many blocked-waiting requests it takes to get the webapp onto its knees, Brian offers that the penalty for uncontended synchronization is somewhere between 10 percent and 200 percent in most cases, but that a contended synchronization may be 50 times slower than an uncontended one.

http://www.ibm.com/developerworks/java/library/j-threads1.html

So for those five simultaneous webapp users, a single synchronized block of code might slow the last guy in by a factor of 500 or so (2*50*5), such that after about 10ms or so in the block, the pain neurons will doubtless begin to fire.
Paul Fenerty
Greenhorn

Joined: May 06, 2005
Posts: 23
A private messager has pointed out that eliminating shared instance variables eliminates the need for synchronization in order to achieve thread-safety.

I had started down this multi-threaded JDBC performance-enhancement path of inquiry with the assumption that a singleton DAO is best, in order to eliminate time wasted in per-request DAO object creation. Such an approach requires a shared instance variable for the DAO's DataSource.

The DataSource was the object i initially thought required guarded access: What if thread 'a' suspends after getting the Connection reference, and then along comes thread 'b', and gets the same one?

But Brian Goetz claims, in the section "Interpreting Vague Documentation" (Java Concurrency in Practice) that while the JDBC specification doesn't guarantee a thread-safe implementation of DataSource.getConnection(), "it would be absurd if it weren't", and so doesn't require additional client-side locking.

According to that, then, if the reference to the returned Connection is only available on the stack, then mr. private messager is correct, and no synchronized access, much less ThreadLocal binding, is required for a thread-safe DAO singleton.

n'cest-ce pas?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: congested webapp connection pools