All pastes #46204 Raw Edit

Gnipi

public text v1 · immutable
#46204 ·published 2006-03-19 06:18 UTC
rendered paste body
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)
@@ -22,12 +22,14 @@
 import java.sql.SQLException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import javax.sql.PooledConnection;
 
 import javax.sql.DataSource;
 
 import com.mchange.v2.c3p0.DataSources;
 import com.mchange.v2.c3p0.PoolConfig;
 import com.mchange.v2.c3p0.PooledDataSource;
+import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource;
 
 public class L2DatabaseFactory
 {
@@ -44,7 +46,6 @@
     private static L2DatabaseFactory _instance;
     private ProviderType _Provider_Type;
 	private DataSource _source;
-	
     // =========================================================
     // Constructor
 	public L2DatabaseFactory() throws SQLException
@@ -58,20 +59,55 @@
             }
 
 			PoolConfig config = new PoolConfig();
-			config.setAutoCommitOnClose(true);
-			config.setInitialPoolSize(1);
+
+			config.setInitialPoolSize(8);   // 8 connections is nothing for sql, 
+											// please don't setup server without at least
+											// 50 connections allowed at same time
+											// sql is server software that is designed
+											// to handle thousands of connections
+											// if > MaxPoolSize, it will be ignored - no worry
+											// (as said in c3p0 docs, it's only a suggestion
+											// how many connections to open at the beginning)
+
 			config.setMinPoolSize(1);
 			config.setMaxPoolSize(Config.DATABASE_MAX_CONNECTIONS);
+
+			
+			config.setAcquireRetryAttempts(0); // try to obtain connections indefinitely
+			config.setAcquireRetryDelay(1);    // retry once per second
+			config.setCheckoutTimeout(0);      // 0 = wait indefinitely for new connection
+											   // if pool is exhausted
+			
+			config.setAutomaticTestTable("connection_test_table");  // very very fast test, don't worry
+			config.setTestConnectionOnCheckout(true);				// this will *not* make l2j slower in any way
+			
+			config.setAutoCommitOnClose(true);
+			config.setAcquireIncrement(8); // if pool exhausted, get 6 more connections
+										   // cause there is a "long" delay
+										   // so taking more than one connection to pool
+										   // will not reduce number of times waiting for
+										   // new connection (which is slow)
+			
 			config.setMaxStatements(100);
-			config.setIdleConnectionTestPeriod(0); // test idle connection every 1 minute
-			config.setMaxIdleTime(0); // remove unused connection after 10 minutes
-
+			
+			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  
+			
+			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 +119,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 +149,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 +186,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 +223,7 @@
 
 	public int getIdleConnectionCount() throws SQLException
 	{
-	    return ((PooledDataSource) _source).getNumIdleConnectionsDefaultUser();
+		return ((PooledDataSource) _source).getNumIdleConnectionsDefaultUser();
 	}
 
     public final ProviderType getProviderType() { return _Provider_Type; }