IDEMPIERE-1093 Database: added connection pool properties file support.

This commit is contained in:
Heng Sin Low 2013-06-21 22:35:31 +08:00
parent aacfdbb197
commit 8c05b86db1
4 changed files with 204 additions and 30 deletions

View File

@ -9,6 +9,7 @@ MaxIdleTime=1200
MaxPoolSize=150 MaxPoolSize=150
InitialPoolSize=10 InitialPoolSize=10
MinPoolSize=5 MinPoolSize=5
MaxStatementsPerConnection=30
#flag #flag
TestConnectionOnCheckin=false TestConnectionOnCheckin=false

View File

@ -16,7 +16,12 @@
*****************************************************************************/ *****************************************************************************/
package org.compiere.db; package org.compiere.db;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.net.URL; import java.net.URL;
import java.sql.Connection; import java.sql.Connection;
@ -49,6 +54,7 @@ import org.compiere.util.Ini;
import org.compiere.util.Language; import org.compiere.util.Language;
import org.compiere.util.Trx; import org.compiere.util.Trx;
import org.compiere.util.Util; import org.compiere.util.Util;
import org.jfree.io.IOUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource; import com.mchange.v2.c3p0.ComboPooledDataSource;
@ -66,6 +72,8 @@ import com.mchange.v2.c3p0.ComboPooledDataSource;
public class DB_Oracle implements AdempiereDatabase public class DB_Oracle implements AdempiereDatabase
{ {
private static final String POOL_PROPERTIES = "pool.properties";
/** /**
* Oracle Database * Oracle Database
*/ */
@ -324,11 +332,11 @@ public class DB_Oracle implements AdempiereDatabase
} // toString } // toString
/** /**
* Get Status * Get Status
* @return status info * @return status info
*/ */
public String getStatus() public String getStatus()
{ {
if (m_ds == null) if (m_ds == null)
{ {
return null; return null;
@ -341,12 +349,15 @@ public class DB_Oracle implements AdempiereDatabase
sb.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections()); sb.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections());
sb.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections()); sb.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections());
sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections()); sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
sb.append(" , # Min Pool Size: ").append(m_ds.getMinPoolSize());
sb.append(" , # Max Pool Size: ").append(m_ds.getMaxPoolSize());
sb.append(" , # Max Statements Cache Per Session: ").append(m_ds.getMaxStatementsPerConnection());
sb.append(" , # Active Transactions: ").append(Trx.getActiveTransactions().length); sb.append(" , # Active Transactions: ").append(Trx.getActiveTransactions().length);
} }
catch (Exception e) catch (Exception e)
{} {}
return sb.toString(); return sb.toString();
} // getStatus } // getStatus
/************************************************************************** /**************************************************************************
@ -545,6 +556,22 @@ public class DB_Oracle implements AdempiereDatabase
return null; return null;
} // getCommands } // getCommands
private String getFileName ()
{
//
String base = null;
if (Ini.isClient())
base = System.getProperty("user.home");
else
base = Ini.getAdempiereHome();
if (base != null && !base.endsWith(File.separator))
base += File.separator;
//
return base + getName() + File.separator + POOL_PROPERTIES;
} // getFileName
/** /**
* Create DataSource * Create DataSource
* @param connection connection * @param connection connection
@ -555,23 +582,78 @@ public class DB_Oracle implements AdempiereDatabase
if (m_ds != null) if (m_ds != null)
return m_ds; return m_ds;
//try fragment contributed properties then default properties InputStream inputStream = null;
URL url = Ini.isClient()
? OracleBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/client.properties") //check property file from home
: OracleBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/server.properties"); String propertyFilename = getFileName();
if (url == null) File propertyFile = null;
{ if (!Util.isEmpty(propertyFilename))
{
propertyFile = new File(propertyFilename);
if (propertyFile.exists() && propertyFile.canRead())
{
try {
inputStream = new FileInputStream(propertyFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
URL url = null;
if (inputStream == null)
{
propertyFile = null;
url = Ini.isClient() url = Ini.isClient()
? OracleBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/client.default.properties") ? OracleBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/client.default.properties")
: OracleBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/server.default.properties"); : OracleBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/server.default.properties");
try {
inputStream = url.openStream();
} catch (IOException e) {
throw new DBException(e);
}
} }
Properties poolProperties = new Properties();
try { Properties poolProperties = new Properties();
poolProperties.load(url.openStream()); try {
poolProperties.load(inputStream);
inputStream.close();
inputStream = null;
} catch (IOException e) { } catch (IOException e) {
throw new DBException(e); throw new DBException(e);
} }
//auto create property file at home folder from default config
if (propertyFile == null)
{
String directoryName = propertyFilename.substring(0, propertyFilename.length() - (POOL_PROPERTIES.length()+1));
File dir = new File(directoryName);
if (!dir.exists())
dir.mkdir();
propertyFile = new File(propertyFilename);
try {
FileOutputStream fos = new FileOutputStream(propertyFile);
inputStream = url.openStream();
IOUtils.getInstance().copyStreams(inputStream, fos);
fos.close();
inputStream.close();
inputStream = null;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null)
{
try {
inputStream.close();
} catch (IOException e) {}
}
int idleConnectionTestPeriod = getIntProperty(poolProperties, "IdleConnectionTestPeriod", 1200); int idleConnectionTestPeriod = getIntProperty(poolProperties, "IdleConnectionTestPeriod", 1200);
int acquireRetryAttempts = getIntProperty(poolProperties, "AcquireRetryAttempts", 2); int acquireRetryAttempts = getIntProperty(poolProperties, "AcquireRetryAttempts", 2);
int maxIdleTimeExcessConnections = getIntProperty(poolProperties, "MaxIdleTimeExcessConnections", 1200); int maxIdleTimeExcessConnections = getIntProperty(poolProperties, "MaxIdleTimeExcessConnections", 1200);
@ -585,7 +667,7 @@ public class DB_Oracle implements AdempiereDatabase
System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog"); System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
//System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "ALL"); //System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "ALL");
ComboPooledDataSource cpds = new ComboPooledDataSource(); ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDataSourceName("AdempiereDS"); cpds.setDataSourceName("iDempiereDS");
cpds.setDriverClass(DRIVER); cpds.setDriverClass(DRIVER);
//loads the jdbc driver //loads the jdbc driver
cpds.setJdbcUrl(getConnectionURL(connection)); cpds.setJdbcUrl(getConnectionURL(connection));
@ -620,6 +702,11 @@ public class DB_Oracle implements AdempiereDatabase
cpds.setMinPoolSize(minPoolSize); cpds.setMinPoolSize(minPoolSize);
cpds.setMaxPoolSize(maxPoolSize); cpds.setMaxPoolSize(maxPoolSize);
m_maxbusyconnections = (int) (maxPoolSize * 0.9); m_maxbusyconnections = (int) (maxPoolSize * 0.9);
//statement pooling
int maxStatementsPerConnection = getIntProperty(poolProperties, "MaxStatementsPerConnection", 0);
if (maxStatementsPerConnection > 0)
cpds.setMaxStatementsPerConnection(maxStatementsPerConnection);
} }
if (unreturnedConnectionTimeout > 0) if (unreturnedConnectionTimeout > 0)

View File

@ -10,6 +10,7 @@ MaxIdleTime=1200
MaxPoolSize=90 MaxPoolSize=90
InitialPoolSize=10 InitialPoolSize=10
MinPoolSize=5 MinPoolSize=5
MaxStatementsPerConnection=30
#flag #flag
TestConnectionOnCheckin=false TestConnectionOnCheckin=false

View File

@ -18,7 +18,12 @@
*****************************************************************************/ *****************************************************************************/
package org.compiere.db; package org.compiere.db;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.net.URL; import java.net.URL;
import java.sql.Connection; import java.sql.Connection;
@ -48,6 +53,7 @@ import org.compiere.util.DisplayType;
import org.compiere.util.Ini; import org.compiere.util.Ini;
import org.compiere.util.Trx; import org.compiere.util.Trx;
import org.compiere.util.Util; import org.compiere.util.Util;
import org.jfree.io.IOUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource; import com.mchange.v2.c3p0.ComboPooledDataSource;
@ -65,7 +71,9 @@ import com.mchange.v2.c3p0.ComboPooledDataSource;
public class DB_PostgreSQL implements AdempiereDatabase public class DB_PostgreSQL implements AdempiereDatabase
{ {
public Convert getConvert() { private static final String POOL_PROPERTIES = "pool.properties";
public Convert getConvert() {
return m_convert; return m_convert;
} }
@ -304,6 +312,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections()); sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
sb.append(" , # Min Pool Size: ").append(m_ds.getMinPoolSize()); sb.append(" , # Min Pool Size: ").append(m_ds.getMinPoolSize());
sb.append(" , # Max Pool Size: ").append(m_ds.getMaxPoolSize()); sb.append(" , # Max Pool Size: ").append(m_ds.getMaxPoolSize());
sb.append(" , # Max Statements Cache Per Session: ").append(m_ds.getMaxStatementsPerConnection());
sb.append(" , # Active Transactions: ").append(Trx.getActiveTransactions().length); sb.append(" , # Active Transactions: ").append(Trx.getActiveTransactions().length);
} }
catch (Exception e) catch (Exception e)
@ -625,6 +634,21 @@ public class DB_PostgreSQL implements AdempiereDatabase
return conn; return conn;
} // getCachedConnection } // getCachedConnection
private String getFileName ()
{
//
String base = null;
if (Ini.isClient())
base = System.getProperty("user.home");
else
base = Ini.getAdempiereHome();
if (base != null && !base.endsWith(File.separator))
base += File.separator;
//
return base + getName() + File.separator + POOL_PROPERTIES;
} // getFileName
/** /**
* Create DataSource (Client) * Create DataSource (Client)
@ -636,23 +660,79 @@ public class DB_PostgreSQL implements AdempiereDatabase
if (m_ds != null) if (m_ds != null)
return m_ds; return m_ds;
//try fragment contributed properties then default properties InputStream inputStream = null;
URL url = Ini.isClient()
? PostgreSQLBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/client.properties") //check property file from home
: PostgreSQLBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/server.properties"); String propertyFilename = getFileName();
if (url == null) File propertyFile = null;
{ if (!Util.isEmpty(propertyFilename))
url = Ini.isClient() {
? PostgreSQLBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/client.default.properties") propertyFile = new File(propertyFilename);
: PostgreSQLBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/server.default.properties"); if (propertyFile.exists() && propertyFile.canRead())
} {
try {
inputStream = new FileInputStream(propertyFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
//fall back to default config
URL url = null;
if (inputStream == null)
{
propertyFile = null;
url = Ini.isClient()
? PostgreSQLBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/client.default.properties")
: PostgreSQLBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/server.default.properties");
try {
inputStream = url.openStream();
} catch (IOException e) {
e.printStackTrace();
}
}
Properties poolProperties = new Properties(); Properties poolProperties = new Properties();
try { try {
poolProperties.load(url.openStream()); poolProperties.load(inputStream);
inputStream.close();
inputStream = null;
} catch (IOException e) { } catch (IOException e) {
throw new DBException(e); throw new DBException(e);
} }
//auto create property file at home folder from default config
if (propertyFile == null)
{
String directoryName = propertyFilename.substring(0, propertyFilename.length() - (POOL_PROPERTIES.length()+1));
File dir = new File(directoryName);
if (!dir.exists())
dir.mkdir();
propertyFile = new File(propertyFilename);
try {
FileOutputStream fos = new FileOutputStream(propertyFile);
inputStream = url.openStream();
IOUtils.getInstance().copyStreams(inputStream, fos);
fos.close();
inputStream.close();
inputStream = null;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null)
{
try {
inputStream.close();
} catch (IOException e) {}
}
int idleConnectionTestPeriod = getIntProperty(poolProperties, "IdleConnectionTestPeriod", 1200); int idleConnectionTestPeriod = getIntProperty(poolProperties, "IdleConnectionTestPeriod", 1200);
int acquireRetryAttempts = getIntProperty(poolProperties, "AcquireRetryAttempts", 2); int acquireRetryAttempts = getIntProperty(poolProperties, "AcquireRetryAttempts", 2);
int maxIdleTimeExcessConnections = getIntProperty(poolProperties, "MaxIdleTimeExcessConnections", 1200); int maxIdleTimeExcessConnections = getIntProperty(poolProperties, "MaxIdleTimeExcessConnections", 1200);
@ -667,7 +747,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog"); System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
//System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "ALL"); //System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "ALL");
ComboPooledDataSource cpds = new ComboPooledDataSource(); ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDataSourceName("AdempiereDS"); cpds.setDataSourceName("iDempiereDS");
cpds.setDriverClass(DRIVER); cpds.setDriverClass(DRIVER);
//loads the jdbc driver //loads the jdbc driver
cpds.setJdbcUrl(getConnectionURL(connection)); cpds.setJdbcUrl(getConnectionURL(connection));
@ -704,6 +784,11 @@ public class DB_PostgreSQL implements AdempiereDatabase
cpds.setMinPoolSize(minPoolSize); cpds.setMinPoolSize(minPoolSize);
cpds.setMaxPoolSize(maxPoolSize); cpds.setMaxPoolSize(maxPoolSize);
m_maxbusyconnections = (int) (maxPoolSize * 0.9); m_maxbusyconnections = (int) (maxPoolSize * 0.9);
//statement pooling
int maxStatementsPerConnection = getIntProperty(poolProperties, "MaxStatementsPerConnection", 0);
if (maxStatementsPerConnection > 0)
cpds.setMaxStatementsPerConnection(maxStatementsPerConnection);
} }
if (unreturnedConnectionTimeout > 0) if (unreturnedConnectionTimeout > 0)