Commit f499120f authored by Alpha's avatar Alpha

Made connection retry parameters configurable

parent 1f032323
...@@ -74,55 +74,59 @@ public class DbConnectionManager { ...@@ -74,55 +74,59 @@ public class DbConnectionManager {
/** True if the database supports the Statement.setFetchSize()) method. */ /** True if the database supports the Statement.setFetchSize()) method. */
static boolean pstmt_fetchSizeSupported = true; static boolean pstmt_fetchSizeSupported = true;
private static final String SETTING_DATABASE_MAX_RETRIES = "database.defaultProvider.maxRetries";
private static final String SETTING_DATABASE_RETRY_DELAY = "database.defaultProvider.retryDelay";
private static DatabaseType databaseType = DatabaseType.unknown; private static DatabaseType databaseType = DatabaseType.unknown;
private static SchemaManager schemaManager = new SchemaManager(); private static SchemaManager schemaManager = new SchemaManager();
/** /**
* Returns a database connection from the currently active connection * Ensures that the connection provider exists and is set
* provider. An exception will be thrown if no connection was found.
* (auto commit is set to true).
*
* @return a connection.
* @throws SQLException if a SQL exception occurs or no connection was found.
*/ */
public static Connection getConnection() throws SQLException { private static void ensureConnectionProvider() {
if (connectionProvider == null) { if (connectionProvider != null) return;
synchronized (providerLock) { synchronized (providerLock) {
if (connectionProvider == null) { if (connectionProvider != null) return;
// Attempt to load the connection provider classname as
// a Jive property. // Attempt to load the connection provider classname as a Jive property.
String className = JiveGlobals.getXMLProperty("connectionProvider.className"); String className = JiveGlobals.getXMLProperty("connectionProvider.className");
if (className != null) { if (className != null) {
// Attempt to load the class. // Attempt to load the class.
try { try {
Class conClass = ClassUtils.forName(className); Class conClass = ClassUtils.forName(className);
setConnectionProvider((ConnectionProvider)conClass.newInstance()); setConnectionProvider((ConnectionProvider)conClass.newInstance());
} } catch (Exception e) {
catch (Exception e) {
Log.warn("Failed to create the " + Log.warn("Failed to create the " +
"connection provider specified by connection" + "connection provider specified by connection" +
"Provider.className. Using the default pool.", e); "Provider.className. Using the default pool.", e);
setConnectionProvider(new DefaultConnectionProvider()); setConnectionProvider(new DefaultConnectionProvider());
} }
} } else {
else {
setConnectionProvider(new DefaultConnectionProvider()); setConnectionProvider(new DefaultConnectionProvider());
} }
} }
} }
}
// TODO: May want to make these settings configurable /**
Integer retryCnt = 0; * Returns a database connection from the currently active connection
Integer retryMax = 10; * provider. An exception will be thrown if no connection was found.
Integer retryWait = 250; // milliseconds * (auto commit is set to true).
Connection con = null; *
* @return a connection.
* @throws SQLException if a SQL exception occurs or no connection was found.
*/
public static Connection getConnection() throws SQLException {
ensureConnectionProvider();
Integer currentRetryCount = 0;
Integer maxRetries = JiveGlobals.getIntProperty(SETTING_DATABASE_MAX_RETRIES, 10);
Integer retryWait = JiveGlobals.getIntProperty(SETTING_DATABASE_RETRY_DELAY, 250); // milliseconds
SQLException lastException = null; SQLException lastException = null;
do { do {
try { try {
con = connectionProvider.getConnection(); Connection con = connectionProvider.getConnection();
if (con != null) { if (con != null) {
// Got one, lets hand it off. // Got one, lets hand it off.
// Usually profiling is not enabled. So we return a normal // Usually profiling is not enabled. So we return a normal
...@@ -130,8 +134,7 @@ public class DbConnectionManager { ...@@ -130,8 +134,7 @@ public class DbConnectionManager {
// connection with a profiled connection. // connection with a profiled connection.
if (!profilingEnabled) { if (!profilingEnabled) {
return con; return con;
} } else {
else {
return new ProfiledConnection(con); return new ProfiledConnection(con);
} }
} }
...@@ -139,19 +142,20 @@ public class DbConnectionManager { ...@@ -139,19 +142,20 @@ public class DbConnectionManager {
// TODO distinguish recoverable from non-recoverable exceptions. // TODO distinguish recoverable from non-recoverable exceptions.
lastException = e; lastException = e;
Log.info("Unable to get a connection from the database pool " + Log.info("Unable to get a connection from the database pool " +
"(attempt "+retryCnt+" out of "+retryMax+").", e); "(attempt " + currentRetryCount + " out of " + maxRetries + ").", e);
} }
try { try {
Thread.sleep(retryWait); Thread.sleep(retryWait);
} catch (Exception e) {
// Ignored, the thread was interrupted while waiting, so no need to log either
} }
catch (Exception e) { currentRetryCount++;
// Ignored } while (currentRetryCount <= maxRetries);
}
retryCnt++;
} while (retryCnt <= retryMax);
throw new SQLException("ConnectionManager.getConnection() " + throw new SQLException("ConnectionManager.getConnection() " +
"failed to obtain a connection after " + retryCnt +" retries. " + "failed to obtain a connection after " + currentRetryCount + " retries. " +
"The exception from the last attempt is as follows: "+lastException); "The exception from the last attempt is as follows: " + lastException);
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment