r10004 - in helma/helma/trunk/src/helma: main objectmodel/db
[email protected] Thu, 17 Dec 2009 11:55:27 +0100 (CET)
| Newsgroups | gmane.comp.java.helma.cvs |
|---|---|
| Message-ID | <20091217105527.288A13D0E2@mia> |
Author: hannes
Date: 2009-12-17 11:55:26 +0100 (Thu, 17 Dec 2009)
New Revision: 10004
Removed:
helma/helma/trunk/src/helma/objectmodel/db/DbConnection.java
Modified:
helma/helma/trunk/src/helma/main/Server.java
helma/helma/trunk/src/helma/objectmodel/db/DbSource.java
helma/helma/trunk/src/helma/objectmodel/db/Transactor.java
Log:
Undo last two commits. The change had some side effects, leave db connection handling as is.
Details at http://dev.helma.org/trac/helma/changeset/10004
Modified: helma/helma/trunk/src/helma/main/Server.java
===================================================================
--- helma/helma/trunk/src/helma/main/Server.java 2009-12-01 11:05:25 UTC (rev 10003)
+++ helma/helma/trunk/src/helma/main/Server.java 2009-12-17 10:55:26 UTC (rev 10004)
@@ -417,6 +417,7 @@
dbProps = new ResourceProperties();
dbProps.setIgnoreCase(false);
dbProps.addResource(new FileResource(file));
+ DbSource.setDefaultProps(dbProps);
// read apps.properties file
String appsPropfile = sysProps.getProperty("appsPropFile");
Deleted: helma/helma/trunk/src/helma/objectmodel/db/DbConnection.java
Modified: helma/helma/trunk/src/helma/objectmodel/db/DbSource.java
===================================================================
--- helma/helma/trunk/src/helma/objectmodel/db/DbSource.java 2009-12-01 11:05:25 UTC (rev 10003)
+++ helma/helma/trunk/src/helma/objectmodel/db/DbSource.java 2009-12-17 10:55:26 UTC (rev 10004)
@@ -27,18 +27,20 @@
import java.util.Hashtable;
/**
- * This class describes a relational data source (URL, driver, user and password).
+ * This class describes a releational data source (URL, driver, user and password).
*/
public class DbSource {
+ private static ResourceProperties defaultProps = null;
+ private Properties conProps;
private String name;
- private int serialId = 0;
- private ResourceProperties props;
+ private ResourceProperties props, subProps;
protected String url;
private String driver;
- private Properties conProps;
private boolean isOracle, isMySQL, isPostgreSQL, isH2;
private long lastRead = 0L;
private Hashtable dbmappings = new Hashtable();
+ // compute hashcode statically because it's expensive and we need it often
+ private int hashcode;
// thread local connection holder for non-transactor threads
private ThreadLocal connection;
@@ -66,47 +68,56 @@
*/
public synchronized Connection getConnection()
throws ClassNotFoundException, SQLException {
- DbConnection con;
+ Connection con;
Transactor tx = Transactor.getInstance();
- if (props.lastModified() != lastRead) {
- init();
- }
if (tx != null) {
- con = tx.getDbConnection(name, serialId);
+ con = tx.getConnection(this);
} else {
- con = getThreadLocalDbConnection();
+ con = getThreadLocalConnection();
}
- if (con == null) {
- con = new DbConnection(DriverManager.getConnection(url, conProps), serialId);
+ boolean fileUpdated = props.lastModified() > lastRead ||
+ (defaultProps != null && defaultProps.lastModified() > lastRead);
+ if (con == null || con.isClosed() || fileUpdated) {
+ init();
+ con = DriverManager.getConnection(url, conProps);
+
// If we wanted to use SQL transactions, we'd set autoCommit to
// false here and make commit/rollback invocations in Transactor methods;
// System.err.println ("Created new Connection to "+url);
if (tx != null) {
- tx.registerConnection(name, con);
+ tx.registerConnection(this, con);
} else {
connection.set(con);
}
}
- return con.getConnection();
+ return con;
}
/**
* Used for connections not managed by a Helma transactor
* @return a thread local tested connection, or null
*/
- private DbConnection getThreadLocalDbConnection() {
+ private Connection getThreadLocalConnection() {
if (connection == null) {
connection = new ThreadLocal();
return null;
}
- DbConnection con = (DbConnection) connection.get();
- if (con != null && !con.isValid(serialId)) {
- con.close();
- connection.remove();
- 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;
}
@@ -131,10 +142,13 @@
* @throws ClassNotFoundException if the JDBC driver couldn't be loaded
*/
private synchronized void init() throws ClassNotFoundException {
- lastRead = props.lastModified();
- serialId ++;
+ lastRead = (defaultProps == null) ? props.lastModified()
+ : Math.max(props.lastModified(),
+ defaultProps.lastModified());
// refresh sub-properties for this DbSource
- ResourceProperties subProps = props.getSubProperties(name + '.');
+ subProps = props.getSubProperties(name + '.');
+ // use properties hashcode for ourselves
+ hashcode = subProps.hashCode();
// get JDBC URL and driver class name
url = subProps.getProperty("url");
driver = subProps.getProperty("driver");
@@ -199,6 +213,15 @@
}
/**
+ * Set the default (server-wide) properties
+ *
+ * @param props server default db.properties
+ */
+ public static void setDefaultProps(ResourceProperties props) {
+ defaultProps = props;
+ }
+
+ /**
* Check if this DbSource represents an Oracle database
*
* @return true if we're using an oracle JDBC driver
@@ -255,4 +278,17 @@
return (DbMapping) dbmappings.get(tablename.toUpperCase());
}
+ /**
+ * Returns a hash code value for the object.
+ */
+ public int hashCode() {
+ return hashcode;
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ */
+ public boolean equals(Object obj) {
+ return obj instanceof DbSource && subProps.equals(((DbSource) obj).subProps);
+ }
}
Modified: helma/helma/trunk/src/helma/objectmodel/db/Transactor.java
===================================================================
--- helma/helma/trunk/src/helma/objectmodel/db/Transactor.java 2009-12-01 11:05:25 UTC (rev 10003)
+++ helma/helma/trunk/src/helma/objectmodel/db/Transactor.java 2009-12-17 10:55:26 UTC (rev 10004)
@@ -234,38 +234,37 @@
/**
* Register a db connection with this transactor thread.
- * @param name the db source name
+ * @param src the db source
* @param con the connection
*/
- public void registerConnection(String name, DbConnection con) {
- DbConnection previous = (DbConnection) sqlConnections.put(name, con);
- if (previous != null) {
- nmgr.app.logEvent("Closing previous connection " + con);
- previous.close();
- }
+ public void registerConnection(DbSource src, Connection con) {
+ sqlConnections.put(src, con);
// we assume a freshly created connection is ok.
- testedConnections.put(name, new Long(System.currentTimeMillis()));
+ testedConnections.put(src, new Long(System.currentTimeMillis()));
}
/**
* Get a db connection that was previously registered with this transactor thread.
- * @param name the db source name
- * @param serialId the current serial id of the db source definition, used for validation
- * @return the connection, or null if no valid connection is available
+ * @param src the db source
+ * @return the connection
*/
- public DbConnection getDbConnection(String name, int serialId) {
- DbConnection con = (DbConnection) sqlConnections.get(name);
- Long tested = (Long) testedConnections.get(name);
+ public Connection getConnection(DbSource src) {
+ Connection con = (Connection) sqlConnections.get(src);
+ Long tested = (Long) testedConnections.get(src);
long now = System.currentTimeMillis();
- // Check if the connection is still valid
- if (con != null
- && (tested == null || now - tested.longValue() > 60000)
- && !con.isValid(serialId)) {
- nmgr.app.logEvent("Closing cached connection " + con);
- sqlConnections.remove(name);
- testedConnections.remove(name);
- con.close();
- return null;
+ if (con != null && (tested == null || now - tested.longValue() > 60000)) {
+ // Check if the connection is still alive by executing a simple statement.
+ try {
+ Statement stmt = con.createStatement();
+ stmt.execute("SELECT 1");
+ stmt.close();
+ testedConnections.put(src, new Long(now));
+ } catch (SQLException sx) {
+ try {
+ con.close();
+ } catch (SQLException ignore) {/* nothing to do */}
+ return null;
+ }
}
return con;
}
@@ -530,11 +529,12 @@
if (sqlConnections != null) {
for (Iterator i = sqlConnections.values().iterator(); i.hasNext();) {
try {
- DbConnection con = (DbConnection) i.next();
+ Connection con = (Connection) i.next();
+
con.close();
nmgr.app.logEvent("Closing DB connection: " + con);
- } catch (Exception x) {
- nmgr.app.logEvent("Error closing DB connection: " + x);
+ } catch (Exception ignore) {
+ // exception closing db connection, ignore
}
}