- PooledConnectionSource: Versuch, das Problem das "idle in transaction" Verbindungen mit PostgreSQL zu lösen. Basiert auf folgendem Beitrag in einer Mailingliste:

http://postgresql.1045698.n5.nabble.com/Re-GENERAL-Idle-in-transaction-state-td2171173.html

- Formatierungen



git-svn-id: https://svn.libreccm.org/ccm/trunk@970 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2011-06-18 17:15:36 +00:00
parent 946e111897
commit a497b70f08
4 changed files with 70 additions and 24 deletions

View File

@ -44,12 +44,13 @@ import org.apache.log4j.Logger;
public class PooledConnectionSource implements ConnectionSource { public class PooledConnectionSource implements ConnectionSource {
private static final Logger s_log = private static final Logger s_log =
Logger.getLogger(PooledConnectionSource.class); Logger.getLogger(PooledConnectionSource.class);
private static CacheTable s_connectionTags = private static CacheTable s_connectionTags =
new CacheTable("jdbcConnectionTags", new CacheTable("jdbcConnectionTags",
RuntimeConfig.getConfig().getJDBCPoolSize() + 10, RuntimeConfig.getConfig().
CacheTable.MAX_CACHE_AGE, getJDBCPoolSize() + 10,
false); CacheTable.MAX_CACHE_AGE,
false);
private String m_url; private String m_url;
private int m_size; private int m_size;
private long m_interval; private long m_interval;
@ -57,7 +58,7 @@ public class PooledConnectionSource implements ConnectionSource {
private List m_available = new ArrayList(); private List m_available = new ArrayList();
private List m_untested = new ArrayList(); private List m_untested = new ArrayList();
private static boolean s_taggingEnabled = private static boolean s_taggingEnabled =
RuntimeConfig.getConfig().isThreadTaggingEnabled(); RuntimeConfig.getConfig().isThreadTaggingEnabled();
public PooledConnectionSource(String url, int size, long interval) { public PooledConnectionSource(String url, int size, long interval) {
m_url = url; m_url = url;
@ -90,7 +91,7 @@ public class PooledConnectionSource implements ConnectionSource {
} else { } else {
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
s_log.debug("Reacquisition failed: " + pref s_log.debug("Reacquisition failed: " + pref
+ ", tag: " + s_connectionTags.get(pref.toString())); + ", tag: " + s_connectionTags.get(pref.toString()));
} }
return acquire(); return acquire();
} }
@ -101,12 +102,35 @@ public class PooledConnectionSource implements ConnectionSource {
if (!m_available.isEmpty()) { if (!m_available.isEmpty()) {
Connection conn = (Connection) m_available.remove(0); Connection conn = (Connection) m_available.remove(0);
renameThread(conn); renameThread(conn);
/**
* jensp 2011-06-18: Change to prevent connections from being
* in "idle in transaction" state. Such connections seam to
* cause problems (memory etc.) with PostgreSQL.
*/
try {
conn.setAutoCommit(false);
} catch (SQLException ex) {
s_log.warn("Failed to set autocommit to false");
}
/**
* jensp end
*/
return conn; return conn;
} else if (m_connections.size() < m_size) { } else if (m_connections.size() < m_size) {
Connection result = (Connection) Connections.acquire(m_url); Connection result = (Connection) Connections.acquire(m_url);
s_connectionTags.put(result.toString(), tag(result)); s_connectionTags.put(result.toString(), tag(result));
m_connections.add(result); m_connections.add(result);
renameThread(result); renameThread(result);
try {
/**
* jensp 2011-06-18: Change to prevent connections from being
* in "idle in transaction" state. Such connections seam to
* cause problems (memory etc.) with PostgreSQL.
*/
result.setAutoCommit(false);
} catch (SQLException ex) {
s_log.warn("Failed to set autocommit to false");
}
return result; return result;
} else { } else {
try { try {
@ -127,7 +151,8 @@ public class PooledConnectionSource implements ConnectionSource {
s_log.warn("Could not obtain conn tag for: " + conn); s_log.warn("Could not obtain conn tag for: " + conn);
return; return;
} }
String newName = tname.replaceAll("(-db[0-9]*)*$", "") + "-db" + ctag; String newName = tname.replaceAll("(-db[0-9]*)*$", "") + "-db"
+ ctag;
if (!tname.equals(newName)) { if (!tname.equals(newName)) {
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
s_log.debug("setting the thread name to: " + newName); s_log.debug("setting the thread name to: " + newName);
@ -170,7 +195,8 @@ public class PooledConnectionSource implements ConnectionSource {
public synchronized void release(Connection conn) { public synchronized void release(Connection conn) {
if (!m_connections.contains(conn)) { if (!m_connections.contains(conn)) {
throw new IllegalArgumentException("connection did come from ths source: " + conn); throw new IllegalArgumentException("connection did come from this source: "
+ conn);
} }
boolean remove; boolean remove;
@ -184,6 +210,19 @@ public class PooledConnectionSource implements ConnectionSource {
if (remove) { if (remove) {
remove(conn); remove(conn);
} else { } else {
/**
* jensp 2011-06-18: Change to prevent connections from being
* in "idle in transaction" state. Such connections seam to
* cause problems (memory etc.) with PostgreSQL.
*/
try {
conn.setAutoCommit(true);
} catch (SQLException ex) {
s_log.warn("Failed to set auto commit to true.");
}
/**
* jensp end
*/
m_available.add(conn); m_available.add(conn);
} }
@ -193,7 +232,8 @@ public class PooledConnectionSource implements ConnectionSource {
private synchronized void remove(Connection conn) { private synchronized void remove(Connection conn) {
m_connections.remove(conn); m_connections.remove(conn);
m_available.remove(conn); m_available.remove(conn);
s_log.info("removed: " + conn + ", tag: " + s_connectionTags.get(conn.toString())); s_log.info("removed: " + conn + ", tag: " + s_connectionTags.get(conn.
toString()));
s_connectionTags.remove(conn.toString()); s_connectionTags.remove(conn.toString());
} }
@ -209,7 +249,7 @@ public class PooledConnectionSource implements ConnectionSource {
public void run() { public void run() {
while (true) { while (true) {
s_log.error("PollerThread run(): " + m_interval); //s_log.error("PollerThread run(): " + m_interval);
try { try {
Thread.sleep(m_interval); Thread.sleep(m_interval);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -245,8 +285,9 @@ public class PooledConnectionSource implements ConnectionSource {
SQLException e = test(conn); SQLException e = test(conn);
if (e != null) { if (e != null) {
s_log.warn("connection " + conn s_log.warn("connection " + conn
+ ", tag: " + s_connectionTags.get(conn.toString()) + ", tag: " + s_connectionTags.get(conn.
+ " failed test", e); toString())
+ " failed test", e);
try { try {
conn.close(); conn.close();
} catch (SQLException ex) { } catch (SQLException ex) {

View File

@ -74,7 +74,21 @@ public final class Connections {
Assert.exists(conn, Connection.class); Assert.exists(conn, Connection.class);
conn.setAutoCommit(false); conn.setAutoCommit(false);
if(s_log.isDebugEnabled()) {
if (conn.getTransactionIsolation() == Connection.TRANSACTION_NONE) {
s_log.debug("transactionIsoliation = NONE");
} else if(conn.getTransactionIsolation() == Connection.TRANSACTION_READ_COMMITTED) {
s_log.debug("transactionIsoliation = READ_COMMITED");
} else if(conn.getTransactionIsolation() == Connection.TRANSACTION_READ_UNCOMMITTED) {
s_log.debug("transactionIsoliation = READ_UNCOMMITTED");
} else if(conn.getTransactionIsolation() == Connection.TRANSACTION_REPEATABLE_READ) {
s_log.debug("transactionIsoliation = REPEATABLE_READ");
} else if(conn.getTransactionIsolation() == Connection.TRANSACTION_SERIALIZABLE) {
s_log.debug("transactionIsoliation = SERIALIZABLE");
}
}
// This is a workaround for a bug in certain versions of // This is a workaround for a bug in certain versions of
// oracle that cause oracle to erroneously report parse // oracle that cause oracle to erroneously report parse
// errors or 0600 errors when a UNION ALL is used in a // errors or 0600 errors when a UNION ALL is used in a

View File

@ -20,9 +20,6 @@
package com.arsdigita.cms.contenttypes.ui; package com.arsdigita.cms.contenttypes.ui;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentItemXMLRenderer;
import com.arsdigita.cms.contentassets.RelatedLink;
import com.arsdigita.cms.contenttypes.GenericOrganizationalUnitContactCollection; import com.arsdigita.cms.contenttypes.GenericOrganizationalUnitContactCollection;
import com.arsdigita.cms.contenttypes.GenericOrganizationalUnitPersonCollection; import com.arsdigita.cms.contenttypes.GenericOrganizationalUnitPersonCollection;
import com.arsdigita.cms.contenttypes.GenericPerson; import com.arsdigita.cms.contenttypes.GenericPerson;
@ -31,13 +28,7 @@ import com.arsdigita.cms.contenttypes.SciDepartment;
import com.arsdigita.cms.contenttypes.SciDepartmentProjectsCollection; import com.arsdigita.cms.contenttypes.SciDepartmentProjectsCollection;
import com.arsdigita.cms.contenttypes.SciDepartmentSubDepartmentsCollection; import com.arsdigita.cms.contenttypes.SciDepartmentSubDepartmentsCollection;
import com.arsdigita.cms.contenttypes.SciProject; import com.arsdigita.cms.contenttypes.SciProject;
import com.arsdigita.cms.dispatcher.SimpleXMLGenerator;
import com.arsdigita.domain.DomainCollection;
import com.arsdigita.domain.DomainObject;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.xml.Element; import com.arsdigita.xml.Element;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;

View File

@ -544,7 +544,7 @@ public class SciOrganizationPanel extends SciOrganizationBasePanel {
final PageState state) { final PageState state) {
show = getShowParam(state); show = getShowParam(state);
SciOrganization organization = (SciOrganization) orga; SciOrganization organization = (SciOrganization) orga;
if (SHOW_DESCRIPTION.equals(show)) { if (SHOW_DESCRIPTION.equals(show)) {
String desc; String desc;