Index: C:/workspace/c4/java/net/sf/l2j/L2DatabaseFactory.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/L2DatabaseFactory.java (revision 1605)
+++ C:/workspace/c4/java/net/sf/l2j/L2DatabaseFactory.java (working copy)
@@ -44,7 +44,6 @@
private static L2DatabaseFactory _instance;
private ProviderType _Provider_Type;
private DataSource _source;
-
// =========================================================
// Constructor
public L2DatabaseFactory() throws SQLException
@@ -59,19 +58,51 @@
PoolConfig config = new PoolConfig();
config.setAutoCommitOnClose(true);
- config.setInitialPoolSize(1);
+ config.setInitialPoolSize(3); // 3 is the default for c3p0 anyway
+ // if > MaxPoolSize, it will be ignored - no worry
+ // (as said in c3p0 docs, it's only a suggestion
+ // how many connections to acquire to start with)
+
config.setMinPoolSize(1);
config.setMaxPoolSize(Config.DATABASE_MAX_CONNECTIONS);
+
+
+ config.setAcquireRetryAttempts(0); // try to obtain connections indefinitely (0 = never quit)
+ config.setAcquireRetryDelay(500); // 500 miliseconds wait before try to acquire connection again
+ config.setCheckoutTimeout(0); // 0 = wait indefinitely for new connection
+ // if pool is exhausted
+ config.setAcquireIncrement(5); // if pool is exhausted, get 5 more connections at a time
+ // cause there is a "long" delay on acquire connection
+ // so taking more than one connection at once will make connection pooling
+ // more effective.
+
+ // this "connection_test_table" is automatically created if not already there
+ config.setAutomaticTestTable("connection_test_table"); // very very fast test, don't worry
+ config.setTestConnectionOnCheckin(true); // this will *not* make l2j slower in any way
+
+ // testing OnCheckin used with IdleConnectionTestPeriod is faster than testing on checkout
+
+ config.setIdleConnectionTestPeriod(60); // test idle connection every 60 sec
+ config.setMaxIdleTime(60*60); // 0 = idle connections never expire
+ // *THANKS* to connection testing configured above
+ // but I prefer to disconnect all connections not used
+ // for more than 1 hour
+
+ // enables statement caching, there is a "semi-bug" in c3p0 0.9.0 but in 0.9.0.2 and later it's fixed
config.setMaxStatements(100);
- config.setIdleConnectionTestPeriod(0); // test idle connection every 1 minute
- config.setMaxIdleTime(0); // remove unused connection after 10 minutes
+ config.setBreakAfterAcquireFailure(false); // never fail if any way possible
+ // setting this to true will make
+ // c3p0 "crash" and refuse to work
+ // till restart thus making acquire
+ // errors "FATAL" ... we don't want that
+ // it should be possible to recover
+
Class.forName(Config.DATABASE_DRIVER).newInstance();
if (Config.DEBUG) _log.fine("Database Connection Working");
-
DataSource unpooled = DataSources.unpooledDataSource(Config.DATABASE_URL, Config.DATABASE_LOGIN, Config.DATABASE_PASSWORD);
- _source = DataSources.pooledDataSource( unpooled, config);
+ _source=DataSources.pooledDataSource( unpooled, config);
/* Test the connection */
_source.getConnection().close();
@@ -83,13 +114,13 @@
}
catch (SQLException x)
{
- if (Config.DEBUG) _log.fine("Database Connection FAILED");
+ if (Config.DEBUG) _log.warning("Database Connection FAILED");
// rethrow the exception
throw x;
}
catch (Exception e)
{
- if (Config.DEBUG) _log.fine("Database Connection FAILED");
+ if (Config.DEBUG) _log.warning("Database Connection FAILED");
throw new SQLException("could not init DB connection:"+e);
}
}
@@ -113,10 +144,10 @@
{
try {
((PooledDataSource) _source).close();
- } catch (SQLException e) {_log.log(Level.INFO, "", e);}
+ } catch (SQLException e) {_log.log(Level.WARNING, "", e);}
try {
DataSources.destroy(_source);
- } catch (SQLException e) {_log.log(Level.INFO, "", e);}
+ } catch (SQLException e) {_log.log(Level.WARNING, "", e);}
}
public final String safetyString(String[] whatToCheck)
@@ -150,9 +181,34 @@
return _instance;
}
- public Connection getConnection() throws SQLException
+ public Connection getConnection() //throws SQLException
{
- return _source.getConnection();
+ Connection con=null;
+
+ try
+ {
+ con=_source.getConnection();
+ } catch (SQLException e)
+ {
+ _log.warning("L2DatabaseFactory: getConnection() failed, trying again "+e);
+
+ try
+ {
+ con=_source.getConnection();
+ } catch (SQLException e2)
+ {
+ _log.warning("L2DatabaseFactory: getConnection() failed again :( "+e2);
+ }
+ }
+
+ if (con==null) {
+ // any ideas what could be done here to "recover" from db errors ?
+ // maybe sleep 15 seconds and try again ? maybe make loop that will not quit
+ // till con!=null ? if we do that here, we can remove all if(con==null) checks
+ // elsewhere and assume we always have valid and tested connection (good idea)
+ _log.severe("L2DatabaseFactory: getConnection() failed completely please edit L2DatabaseFactory.java on line 213 - add some smart code to avoid this");
+ }
+ return con;
}
public int getBusyConnectionCount() throws SQLException
@@ -162,7 +218,7 @@
public int getIdleConnectionCount() throws SQLException
{
- return ((PooledDataSource) _source).getNumIdleConnectionsDefaultUser();
+ return ((PooledDataSource) _source).getNumIdleConnectionsDefaultUser();
}
public final ProviderType getProviderType() { return _Provider_Type; }