From: <ssk...@vh...> - 2005-09-14 20:17:53
|
Author: sskracic Date: 2005-09-14 22:08:43 +0200 (Wed, 14 Sep 2005) New Revision: 809 Modified: ccm-core/trunk/src/com/arsdigita/persistence/PooledConnectionSource.java Log: Connection acquisition should go LIFO, and not FIFO. Why? Imagine that, at some point in time, server has 10 available connections (and production servers can have 100+ available connections). Let's label them conn1, conn2, ..., conn10. Now suppose a non-DML (ie. SELECT only) request comes which fires say 50 queries. Those queries will be distributed like this: 1st query : conn1 2nd query : conn2 3rd query : conn3 .. 10th query : conn10 11th query : conn1 12th query : conn2 .. Not only this is extremely inefficient when it comes to network layer, but it also defeats the whole purpose of server-side database caching, since a single request can be distributed among 100 different database backends!! And finally, it makes debugging database problems (eg. deadlocking due to horrendous code at some places) almost impossible. The patch addresses this issue by trying to reacquire the same database connection it has just released. It will not always succeed, since the persistence pooling mechanism is designed in a way that acquired connection is used as little time as possible. Hence whenever we're doing some Java CPU cycles between two database requests our just-released db connection can get acquired by some other thread. But in majority of cases (like 99%) we will acquire the same connection throughout the whole request. Modified: ccm-core/trunk/src/com/arsdigita/persistence/PooledConnectionSource.java =================================================================== --- ccm-core/trunk/src/com/arsdigita/persistence/PooledConnectionSource.java 2005-09-14 19:51:59 UTC (rev 808) +++ ccm-core/trunk/src/com/arsdigita/persistence/PooledConnectionSource.java 2005-09-14 20:08:43 UTC (rev 809) @@ -71,7 +71,7 @@ public synchronized Connection acquire() { while (true) { if (!m_available.isEmpty()) { - return (Connection) m_available.remove(0); + return (Connection) m_available.remove(m_available.size()-1); } else if (m_connections.size() < m_size) { Connection result = (Connection) Connections.acquire(m_url); m_connections.add(result); |