views:

58

answers:

2

Trying to figure out how to manage/use long-living DB connections. I have too little experience of this kind, as I have used DB only with small systems (up to some 150 concurrent users, each one had its own DB user/pass, so there were up to 150 long-living DB connections at any time) or web pages (each page request has its own DB connection that lasts for less than a second, so number of concurrent DB conncetions isn't huge).

This time there will be a Java server and Flash client. Java connects to PostgreSQL. Connections are expected to be long-living, i.e., they're expected to start when Flash client connects to Java server and to end when Flash client disconnects. Would it be better to share single connection between all users (clients) or to make private connection for every client? Or some other solution would be better?

*) Single/shared connection:

  • (+) pros
    • only one DB connection for whole system
  • (-) cons:
    • transactions can't be used (e.g., "user1.startTransaction(); user1.updateBooks(); user2.updateBooks(); user1.rollback();" to a single shared connection would rollback changes that are done by user2)
    • long queries of one user might affect other users (not sure about this, though)

*) Private connections:

  • (+) pros
    • no problems with transactions :)
  • (-) cons:
    • huge number of concurrent connections might be required, i.e., if there are 10000 users online, 10000 DB connections are required, which seems to be too high number :) I don't know anything about expected number of users though, as we are still in process of researching and planning.

One solution would be to introduce timeouts, i.e., if DB connection is not used for 15/60/900(?) seconds, it gets disconnected. When user again needs a DB, it gets reconnected. This seems to be a good solution for me, but I would like to know what might be the reasonable limits for this, e.g., what might be the max number of concurrent DB connections, what timeout should be used etc.

Another solution would be to group queries into two "types" - one type that can safely use single shared long-living connection (e.g., "update user set last_visit = now() where id = :user_id"), and another type that needs a private short-living connection (e.g., something that can potentially do some heavy work or use transactions). This solution does not seem to be appealing for me, though if that's the way it should be done, I could try to do this...

So... What do other developers do in such cases? Are there any other reasonable solutions?

+5  A: 

I don't use long-lived connections. I use a connection pool to manage connections, and I keep them only for as long as it takes to perform an operation: get the connection, perform my SQL operation, return the connection to the pool. It's much more scalable and doesn't suffer from transaction problems.

Let the container manage the pool for you - that's what it's for.

duffymo
Beat me to it. Basically thats the best way to work.
Wes
Seems good. Let's see what others will say. Btw, those connections in pool do stay connected, don't they?
binaryLV
The connection pool handles everything. You can configure it to check for stale connections before it hands them out. The cost of opening connections is amortized over all requests. You're guaranteed that when one is checked out it's ready for use.
duffymo
+1: Connection pools is the correct alternative to "one user, one connection".
Thorbjørn Ravn Andersen
@binaryLV connection pools may not be indefinate. A good connection pool will check if all the persistant connections are working and close down recreate broken ones. Pooling depends on the containers implementation. But yes it can be effective. We can get thousands of connections from a pool as small as 10. Depending on your queries and the database involved you need to configure the number of connections differently. E.g. if you have slow queries (hours) you may need many more connections in the pool.
Wes
Thanks for your answers :) Got the basic idea of "pooled connections", doesn't seem to be anything complicated ;) And tuning numbers will probably be done when there is more information about real-life needs and resources.
binaryLV
A: 

By using single connection, you also get very low performance because the database server will only allocate one connection for you.

You definitely need a connection pool. If you app runs inside an application server, use the container pool. Or you can use a connection pool library like c3p0.

Jason