* Implement thread local connection caching for non-transactor threads.
Fixes problem with connection proliferation with helmaswarm id generator (see http://helma.org/bugs/show_bug.cgi?id=527)
This commit is contained in:
parent
d7618448fb
commit
8579a68675
1 changed files with 34 additions and 1 deletions
|
@ -21,6 +21,7 @@ import helma.util.ResourceProperties;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
@ -40,6 +41,8 @@ public class DbSource {
|
||||||
private Hashtable dbmappings = new Hashtable();
|
private Hashtable dbmappings = new Hashtable();
|
||||||
// compute hashcode statically because it's expensive and we need it often
|
// compute hashcode statically because it's expensive and we need it often
|
||||||
private int hashcode;
|
private int hashcode;
|
||||||
|
// thread local connection holder for non-transactor threads
|
||||||
|
private ThreadLocal connection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new DbSource object.
|
* Creates a new DbSource object.
|
||||||
|
@ -65,11 +68,13 @@ public class DbSource {
|
||||||
*/
|
*/
|
||||||
public synchronized Connection getConnection()
|
public synchronized Connection getConnection()
|
||||||
throws ClassNotFoundException, SQLException {
|
throws ClassNotFoundException, SQLException {
|
||||||
Connection con = null;
|
Connection con;
|
||||||
Transactor tx = null;
|
Transactor tx = null;
|
||||||
if (Thread.currentThread() instanceof Transactor) {
|
if (Thread.currentThread() instanceof Transactor) {
|
||||||
tx = (Transactor) Thread.currentThread();
|
tx = (Transactor) Thread.currentThread();
|
||||||
con = tx.getConnection(this);
|
con = tx.getConnection(this);
|
||||||
|
} else {
|
||||||
|
con = getThreadLocalConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean fileUpdated = props.lastModified() > lastRead ||
|
boolean fileUpdated = props.lastModified() > lastRead ||
|
||||||
|
@ -84,12 +89,40 @@ public class DbSource {
|
||||||
// System.err.println ("Created new Connection to "+url);
|
// System.err.println ("Created new Connection to "+url);
|
||||||
if (tx != null) {
|
if (tx != null) {
|
||||||
tx.registerConnection(this, con);
|
tx.registerConnection(this, con);
|
||||||
|
} else {
|
||||||
|
connection.set(con);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return con;
|
return con;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for connections not managed by a Helma transactor
|
||||||
|
* @return a thread local tested connection, or null
|
||||||
|
*/
|
||||||
|
private Connection getThreadLocalConnection() {
|
||||||
|
if (connection == null) {
|
||||||
|
connection = new ThreadLocal();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Connection con = (Connection) connection.get();
|
||||||
|
if (con != null) {
|
||||||
|
// test if connection is still ok
|
||||||
|
try {
|
||||||
|
Statement stmt = con.createStatement();
|
||||||
|
stmt.execute("SELECT 1");
|
||||||
|
stmt.close();
|
||||||
|
} catch (SQLException sx) {
|
||||||
|
try {
|
||||||
|
con.close();
|
||||||
|
} catch (SQLException ignore) {/* nothing to do */}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the db properties to newProps, and return the old properties.
|
* Set the db properties to newProps, and return the old properties.
|
||||||
* @param newProps the new properties to use for this db source
|
* @param newProps the new properties to use for this db source
|
||||||
|
|
Loading…
Add table
Reference in a new issue