Question: What is the best way to manage a database connection in a Java servlet?

Currently, I simply open a connection in the `init()` function, and then close it in `destroy()`. 

However, I am concerned that "permanently" holding onto a database connection could be a bad thing. 

Is this the correct way to handle this? If not, what are some better options?

edit: to give a bit more clarification: I have tried simply opening/closing a new connection for each request, but with testing I've seen performance issues due to creating too many connections.

Is there any value in sharing a connection over multiple requests? The requests for this application are almost all "read-only" and come fairly rapidly (although the data requested is fairly small).

Answer: 
As everybody says, you need to use a connection pool. Why? What up? Etc.

**What's Wrong With Your Solution**

I know this since I also thought it was a good idea once upon a time. The problem is two-fold:

1. All threads (servlet requests get served with one thread per each) will be sharing the same connection. The requests will therefore get processed one at a time. This is very slow, even if you just sit in a single browser and lean on the F5 key. Try it: this stuff sounds high-level and abstract, but it's empirical and testable.
2. If the connection breaks for any reason, the init method will not be called again (because the servlet will not be taken out of service). Do not try to handle this problem by putting a try-catch in the doGet or doPost, because then you will be in hell (sort of writing an app server without being asked).
3. Contrary to what one might think, you will not have problems with transactions, since the transaction start gets associated with the thread and not just the connection. I might be wrong, but since this is a bad solution anyway, don't sweat it.

**Why Connection Pool**

Connection pools give you a whole bunch of advantages, but most of all they solve the problems of 

1. Making a real database connection is costly. The connection pool always has a few extra connections around and gives you one of those.
2. If the connections fail, the connection pool knows how to open a new one
3. Very important: every thread gets its own connection. This means that threading is handled where it should be: at the DB level. DBs are super efficient and can handle concurrent request with ease.
4. Other stuff (like centralizing location of JDBC connect strings, etc.), but there are millions of articles, books, etc. on this

**When to Get a Connection**

Somewhere in the call stack initiated in your service delegate (doPost, doGet, doDisco, whatever) you should get a connection and then you should do the right thing and return it in a finally block. I should mention that the C# main architect dude said once up a time that you should use `finally` blocks 100x more than `catch` blocks. Truer words never spoken...

**Which Connection Pool**

You're in a servlet, so you should use the connection pool the container provides. Your JNDI code will be completely normal except for how you obtain the connection. As far as I know, all servlet containers have connection pools. 

Some of the comments on the answers above suggest using a particular connection pool API instead. Your WAR should be portable and "just deploy." I think this is basically wrong. If you use the connection pool provided by your container, your app will be deployable on containers that span multiple machines and all that fancy stuff that the Java EE spec provides. Yes, the container-specific deployment descriptors will have to be written, but that's the EE way, mon.

One commenter mentions that certain container-provided connection pools do not work with JDBC drivers (he/she mentions Websphere). That sounds totally far-fetched and ridiculous, so it's probably true. When stuff like that happens, throw everything you're "supposed to do" in the garbage and do whatever you can. That's what we get paid for, sometimes :)
Are you pooling your connections? If not, you probably should to reduce the overhead of opening and closing your connections.

Once that's out of the way, just keep the connection open for as long as it's need, as John suggested.