[ 1801842 ] DB connection fix & improvements for concurrent threads.

- Integrating contribution from the Posterita Team.
This commit is contained in:
Heng Sin Low 2007-09-26 09:08:59 +00:00
parent 67798db401
commit 87002bb763
8 changed files with 3681 additions and 3786 deletions

View File

@ -18,5 +18,6 @@
<classpathentry kind="lib" path="/tools/lib/postgresql.jar"/> <classpathentry kind="lib" path="/tools/lib/postgresql.jar"/>
<classpathentry kind="lib" path="/tools/lib/ocrs12.jar"/> <classpathentry kind="lib" path="/tools/lib/ocrs12.jar"/>
<classpathentry kind="lib" path="/tools/lib/ojdbc14.jar"/> <classpathentry kind="lib" path="/tools/lib/ojdbc14.jar"/>
<classpathentry kind="lib" path="/tools/lib/c3p0-0.9.1.2.jar"/>
<classpathentry kind="output" path="build"/> <classpathentry kind="output" path="build"/>
</classpath> </classpath>

View File

@ -276,6 +276,10 @@ public interface AdempiereDatabase
// public String getDataType (int displayType, int precision, // public String getDataType (int displayType, int precision,
// boolean defaultValue) // boolean defaultValue)
/**
* Default sql use to test whether a connection is still valid
*/
public final static String DEFAULT_CONN_TEST_SQL = "SELECT Version FROM AD_System";
} // AdempiereDatabase } // AdempiereDatabase

View File

@ -16,25 +16,45 @@
*****************************************************************************/ *****************************************************************************/
package org.compiere.db; package org.compiere.db;
import java.math.*; import java.math.BigDecimal;
import java.sql.*; import java.sql.Connection;
import java.util.*; import java.sql.DatabaseMetaData;
import java.util.logging.*; import java.sql.Driver;
import javax.sql.*; import java.sql.DriverManager;
import oracle.jdbc.*; import java.sql.PreparedStatement;
import oracle.jdbc.pool.*; import java.sql.SQLException;
import org.compiere.*; import java.sql.Statement;
import java.sql.Timestamp;
import java.util.logging.Level;
import javax.sql.DataSource;
import oracle.jdbc.OracleDriver;
import org.compiere.Adempiere;
import org.compiere.dbPort.Convert; import org.compiere.dbPort.Convert;
import org.compiere.dbPort.Convert_Oracle; import org.compiere.dbPort.Convert_Oracle;
import org.compiere.util.*; import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Ini;
import org.compiere.util.Language;
import org.compiere.util.Util;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/** /**
* Oracle Database Port * Oracle Database Port
* *
* @author Jorg Janke * @author Jorg Janke
* @version $Id: DB_Oracle.java,v 1.7 2006/09/22 23:35:19 jjanke Exp $ * @version $Id: DB_Oracle.java,v 1.7 2006/09/22 23:35:19 jjanke Exp $
* ---
* Modifications: Refactoring. Replaced Oracle Cache Manager with C3P0
* connection pooling framework for better and more efficient connnection handling
*
* @author Ashley Ramdass (Posterita)
*/ */
public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallback public class DB_Oracle implements AdempiereDatabase
{ {
/** /**
* Oracle Database * Oracle Database
@ -77,16 +97,10 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
private String m_connectionURL; private String m_connectionURL;
/** Statement Cache (50) */ /** Statement Cache (50) */
private static final int MAX_STATEMENTS = 50; private static final String MAX_STATEMENTS = "200";
/** Data Source */ /** Data Source */
private OracleDataSource m_ds = null; private ComboPooledDataSource m_ds = null;
/** Use Connection Cache (false)*/
private static final boolean USE_CACHE = false;
/** Connection Cache */
private OracleConnectionCacheManager m_cacheMgr = null;
/** Connection Cache Name */
private static final String CACHE_NAME = "AdempiereCCache";
/** Cached User Name */ /** Cached User Name */
private String m_userName = null; private String m_userName = null;
@ -96,27 +110,7 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
private static CLogger log = CLogger.getCLogger (DB_Oracle.class); private static CLogger log = CLogger.getCLogger (DB_Oracle.class);
/** private static int m_maxbusyconnections = 0;
* Check if a connect is valid
* conn Connection
* @return true if connection is valid
*/
public boolean isConnectionValid(Connection conn)
{
try
{
if (((OracleConnection)conn).pingDatabase(1) < 0)
{
return false;
}
else
return true;
}
catch (SQLException e)
{
return false;
}
}
/** /**
@ -306,15 +300,11 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
sb.append(m_connectionURL); sb.append(m_connectionURL);
try try
{ {
if (m_ds != null) StringBuffer logBuffer = new StringBuffer(50);
sb.append("-").append(m_ds.getDataSourceName()) logBuffer.append("# Connections: ").append(m_ds.getNumConnections());
// .append(",ExplCache=").append(m_ds.getExplicitCachingEnabled()) logBuffer.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections());
.append(",ImplCache=").append(m_ds.getImplicitCachingEnabled()) logBuffer.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections());
.append(",MaxStmts=").append(m_ds.getMaxStatements()); logBuffer.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
// .append(",Ref=").append(m_ds.getReference());
if (m_cacheMgr != null && m_cacheMgr.existsCache(CACHE_NAME))
sb.append(";ConnectionActive=").append(m_cacheMgr.getNumberOfActiveConnections(CACHE_NAME))
.append(",CacheAvailable=").append(m_cacheMgr.getNumberOfAvailableConnections(CACHE_NAME));
} }
catch (Exception e) catch (Exception e)
{ {
@ -330,12 +320,18 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
*/ */
public String getStatus() public String getStatus()
{ {
if (m_ds == null)
{
return null;
}
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
try try
{ {
if (m_cacheMgr != null && m_cacheMgr.existsCache(CACHE_NAME)) sb.append("# Connections: ").append(m_ds.getNumConnections());
sb.append("-Connections=").append(m_cacheMgr.getNumberOfActiveConnections(CACHE_NAME)) sb.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections());
.append(",Cache=").append(m_cacheMgr.getNumberOfAvailableConnections(CACHE_NAME)); sb.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections());
sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
} }
catch (Exception e) catch (Exception e)
{} {}
@ -547,76 +543,53 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
{ {
if (m_ds != null) if (m_ds != null)
return m_ds; return m_ds;
try try
{ {
m_ds = new OracleDataSource(); System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
m_ds.setDriverType("thin"); ComboPooledDataSource cpds = new ComboPooledDataSource();
m_ds.setNetworkProtocol("tcp"); cpds.setDataSourceName("AdempiereDS");
m_ds.setServerName(connection.getDbHost()); cpds.setDriverClass(DRIVER);
m_ds.setServiceName(connection.getDbName()); //loads the jdbc driver
m_ds.setPortNumber(connection.getDbPort()); cpds.setJdbcUrl(getConnectionURL(connection));
m_ds.setUser(connection.getDbUid()); cpds.setUser(connection.getDbUid());
m_ds.setPassword(connection.getDbPwd()); cpds.setPassword(connection.getDbPwd());
// cpds.setPreferredTestQuery(DEFAULT_CONN_TEST_SQL);
m_ds.setDataSourceName("AdempiereDS"); cpds.setIdleConnectionTestPeriod(120);
m_ds.setDescription("Adempiere Oracle Data Source"); cpds.setAcquireRetryAttempts(5);
m_ds.setImplicitCachingEnabled(true); //cpds.setCheckoutTimeout(60);
m_ds.setExplicitCachingEnabled(true);
m_ds.setMaxStatements(MAX_STATEMENTS);
// http://download-east.oracle.com/docs/cd/B14117_01/java.101/b10979/oralob.htm#sthref1258
Properties connProperties = new Properties();
//http://www.db.cs.ucdavis.edu/teaching/165B-SQ06/Project/Readme.txt BUG-1568923
//bug [ 1568770 ] Oracle CLOBs are limited in size
connProperties.setProperty("SetBigStringTryClob", "true");
m_ds.setConnectionProperties(connProperties);
//
Properties cacheProperties = new Properties();
// cacheProperties.setProperty("InitialLimit", "3"); // at startup
// cacheProperties.setProperty("MaxStatementsLimit", "10");
cacheProperties.setProperty("ClosestConnectionMatch", "true");
cacheProperties.setProperty("ValidateConnection", "true");
if (Ini.isClient()) if (Ini.isClient())
{ {
cacheProperties.setProperty("MinLimit", "0"); cpds.setInitialPoolSize(1);
// cacheProperties.setProperty("MaxLimit", "5"); cpds.setMinPoolSize(1);
cacheProperties.setProperty("InactivityTimeout", "300"); // 5 Min cpds.setMaxPoolSize(15);
cacheProperties.setProperty("AbandonedConnectionTimeout", "300"); // 5 Min cpds.setMaxIdleTimeExcessConnections(1200);
cpds.setMaxIdleTime(600);
m_maxbusyconnections = 12;
} }
else // Server Settings else
{ {
cacheProperties.setProperty("MinLimit", "3"); cpds.setInitialPoolSize(10);
// cacheProperties.setProperty("MaxLimit", "5"); cpds.setMinPoolSize(5);
cacheProperties.setProperty("InactivityTimeout", "600"); // 10 Min cpds.setMaxPoolSize(150);
cacheProperties.setProperty("AbandonedConnectionTimeout", "600"); // 10 Min cpds.setMaxIdleTimeExcessConnections(1200);
cpds.setMaxIdleTime(900);
m_maxbusyconnections = 120;
} }
cacheProperties.setProperty("PropertyCheckInterval", "120"); // 2 Min
// cpds.setUnreturnedConnectionTimeout(1200);
if (USE_CACHE) cpds.setDebugUnreturnedConnectionStackTraces(true);
m_ds = cpds;
}
catch (Exception ex)
{ {
m_ds.setConnectionCachingEnabled(true); m_ds = null;
m_ds.setConnectionCacheName(CACHE_NAME); log.log(Level.SEVERE, "Could not initialise C3P0 Datasource", ex);
m_ds.setFastConnectionFailoverEnabled(true);
} }
//
if (m_cacheMgr == null && USE_CACHE)
{
m_cacheMgr = OracleConnectionCacheManager.getConnectionCacheManagerInstance();
if (!m_cacheMgr.existsCache(CACHE_NAME))
m_cacheMgr.createCache(CACHE_NAME, m_ds, cacheProperties);
}
// test
// OracleConnection con = m_ds.getConnection();
// con.close();
//
log.config(toString());
//
return m_ds; return m_ds;
}
catch (Exception e)
{
log.log(Level.SEVERE, toString(), e);
}
return null;
} // getDataSource } // getDataSource
@ -632,15 +605,14 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
boolean autoCommit, int transactionIsolation) boolean autoCommit, int transactionIsolation)
throws Exception throws Exception
{ {
OracleConnection conn = null; Connection conn = null;
Exception exception = null; Exception exception = null;
try try
{ {
if (USE_CACHE && m_cacheMgr == null)
getDataSource(connection);
if (m_ds == null) if (m_ds == null)
getDataSource(connection); getDataSource(connection);
// Properties connAttr = new Properties(); // Properties connAttr = new Properties();
// connAttr.setProperty("TRANSACTION_ISOLATION", CConnection.getTransactionIsolationInfo(transactionIsolation)); // connAttr.setProperty("TRANSACTION_ISOLATION", CConnection.getTransactionIsolationInfo(transactionIsolation));
// OracleConnection conn = (OracleConnection)m_ds.getConnection(connAttr); // OracleConnection conn = (OracleConnection)m_ds.getConnection(connAttr);
@ -650,14 +622,14 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
{ {
try try
{ {
conn = (OracleConnection)m_ds.getConnection(); conn = (Connection)m_ds.getConnection();
if (conn != null) if (conn != null)
{ {
if (conn.getTransactionIsolation() != transactionIsolation) if (conn.getTransactionIsolation() != transactionIsolation)
conn.setTransactionIsolation(transactionIsolation); conn.setTransactionIsolation(transactionIsolation);
if (conn.getAutoCommit() != autoCommit) if (conn.getAutoCommit() != autoCommit)
conn.setAutoCommit(autoCommit); conn.setAutoCommit(autoCommit);
conn.setDefaultRowPrefetch(20); // 10 default - reduces round trips // conn.setDefaultRowPrefetch(20); // 10 default - reduces round trips
} }
} }
catch (Exception e) catch (Exception e)
@ -696,7 +668,7 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
{ {
log.log(Level.SEVERE, exception.toString()); log.log(Level.SEVERE, exception.toString());
log.fine(toString()); log.fine(toString());
log.finest("Reference=" + m_ds.getReference()); // log.finest("Reference=" + m_ds.getReference());
} }
// else // else
// { // {
@ -711,6 +683,20 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
// e.printStackTrace(); // e.printStackTrace();
exception = e; exception = e;
} }
try
{
int numConnections = m_ds.getNumBusyConnections();
//if (numConnections > m_maxbusyconnections)
if(numConnections % 10 == 0)
{
log.warning(getStatus());
}
}
catch (Exception ex)
{
}
if (exception != null) if (exception != null)
throw exception; throw exception;
return conn; return conn;
@ -756,26 +742,11 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
{ {
m_ds.close(); m_ds.close();
} }
catch (SQLException e) catch (Exception e)
{ {
e.printStackTrace(); log.log(Level.SEVERE, "Could not close Data Source");
} }
} }
if (m_cacheMgr != null)
{
try
{
if (m_cacheMgr.existsCache(CACHE_NAME))
m_cacheMgr.purgeCache(CACHE_NAME, false); // not active
// m_cache.disableCache(CACHE_NAME);
// m_cache.removeCache(CACHE_NAME, 0);
}
catch (SQLException e)
{
e.printStackTrace();
}
}
m_cacheMgr = null;
m_ds = null; m_ds = null;
} // close } // close
@ -784,58 +755,9 @@ public class DB_Oracle implements AdempiereDatabase, OracleConnectionCacheCallba
*/ */
public void cleanup() public void cleanup()
{ {
if (!USE_CACHE)
return;
log.config("");
try
{
if (m_cacheMgr == null)
m_cacheMgr = OracleConnectionCacheManager.getConnectionCacheManagerInstance();
String[] cacheNames = m_cacheMgr.getCacheNameList();
for (int i = 0; i < cacheNames.length; i++)
{
String name = cacheNames[i];
System.out.println(" cleanup: " + name);
System.out.println(" Before = Active=" + m_cacheMgr.getNumberOfActiveConnections(name)
+ ", Available=" + m_cacheMgr.getNumberOfAvailableConnections(name));
m_cacheMgr.purgeCache(name, false);
System.out.println(" Cached = Active=" + m_cacheMgr.getNumberOfActiveConnections(name)
+ ", Available=" + m_cacheMgr.getNumberOfAvailableConnections(name));
m_cacheMgr.purgeCache(name, true);
System.out.println(" All = Active=" + m_cacheMgr.getNumberOfActiveConnections(name)
+ ", Available=" + m_cacheMgr.getNumberOfAvailableConnections(name));
}
}
catch (Exception e)
{
e.printStackTrace();
}
} // cleanup } // cleanup
/**************************************************************************
* Handle Abandoned Connection
* @param conn connection
* @param userObject
* @return true if close - false for keeping it
*/
public boolean handleAbandonedConnection (OracleConnection conn, Object userObject)
{
System.out.println("--------------------handleAbandonedConnection " + conn + " - " + userObject);
return true; // reclaim it
} // handleAbandonedConnection
/**
* Release Connection
* @param conn connection
* @param userObject
*/
public void releaseConnection (OracleConnection conn, Object userObject)
{
System.out.println("----------------------releaseConnection " + conn + " - " + userObject);
} // releaseConnection
/** /**
* Get Data Type * Get Data Type
* @param columnName * @param columnName

View File

@ -35,15 +35,24 @@ import org.compiere.dbPort.Convert;
import org.compiere.dbPort.Convert_PostgreSQL; import org.compiere.dbPort.Convert_PostgreSQL;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
import org.compiere.util.Ini;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/** /**
* PostgreSQL Database Port * PostgreSQL Database Port
* *
* @author @author Jorg Janke, Victor P<EFBFBD>rez * @author @author Jorg Janke, Victor P<EFBFBD>rez
* @version $Id: DB_PostgreSQL.java,v 1.23 2005/03/11 20:29:01 jjanke Exp $ * @version $Id: DB_PostgreSQL.java,v 1.23 2005/03/11 20:29:01 jjanke Exp $
* ---
* Modifications: removed static references to database connection and instead always
* get a new connection from database pool manager which manages all connections
* set rw/ro properties for the connection accordingly.
* @author Ashley Ramdass (Posterita)
*/ */
public class DB_PostgreSQL implements AdempiereDatabase public class DB_PostgreSQL implements AdempiereDatabase
{ {
public Convert getConvert() { public Convert getConvert() {
return m_convert; return m_convert;
} }
@ -58,11 +67,14 @@ public class DB_PostgreSQL implements AdempiereDatabase
/** Driver */ /** Driver */
private org.postgresql.Driver s_driver = null; private org.postgresql.Driver s_driver = null;
/** Driver class */
public static final String DRIVER = "org.postgresql.Driver";
/** Default Port */ /** Default Port */
public static final int DEFAULT_PORT = 5432; public static final int DEFAULT_PORT = 5432;
/** Data Source */ /** Data Source */
private org.postgresql.ds.PGPoolingDataSource m_ds = null; private ComboPooledDataSource m_ds = null;
/** Statement Converter */ /** Statement Converter */
private Convert_PostgreSQL m_convert = new Convert_PostgreSQL(); private Convert_PostgreSQL m_convert = new Convert_PostgreSQL();
@ -80,6 +92,8 @@ public class DB_PostgreSQL implements AdempiereDatabase
/** Logger */ /** Logger */
private static CLogger log = CLogger.getCLogger (DB_PostgreSQL.class); private static CLogger log = CLogger.getCLogger (DB_PostgreSQL.class);
private static int m_maxbusyconnections = 0;
/** /**
* Get Database Name * Get Database Name
* @return database short name * @return database short name
@ -220,8 +234,20 @@ public class DB_PostgreSQL implements AdempiereDatabase
public String toString() public String toString()
{ {
StringBuffer sb = new StringBuffer("DB_PostgreSQL["); StringBuffer sb = new StringBuffer("DB_PostgreSQL[");
sb.append(m_connection) sb.append(m_connectionURL);
.append("]"); try
{
StringBuffer logBuffer = new StringBuffer(50);
logBuffer.append("# Connections: ").append(m_ds.getNumConnections());
logBuffer.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections());
logBuffer.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections());
logBuffer.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
}
catch (Exception e)
{
sb.append("=").append(e.getLocalizedMessage());
}
sb.append("]");
return sb.toString(); return sb.toString();
} // toString } // toString
@ -231,7 +257,22 @@ public class DB_PostgreSQL implements AdempiereDatabase
*/ */
public String getStatus() public String getStatus()
{ {
return ""; if (m_ds == null)
{
return null;
}
StringBuffer sb = new StringBuffer();
try
{
sb.append("# Connections: ").append(m_ds.getNumConnections());
sb.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections());
sb.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections());
sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
}
catch (Exception e)
{}
return sb.toString();
} // getStatus } // getStatus
/************************************************************************* /*************************************************************************
@ -482,20 +523,50 @@ public class DB_PostgreSQL implements AdempiereDatabase
if (m_ds != null) if (m_ds != null)
return m_ds; return m_ds;
//org.postgresql.ds.PGPoolingDataSource ds = new org.postgresql.ds.PGPoolingDataSource(); try
org.postgresql.jdbc3.Jdbc3PoolingDataSource ds = new org.postgresql.jdbc3.Jdbc3PoolingDataSource(); {
System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDataSourceName("AdempiereDS");
cpds.setDriverClass(DRIVER);
//loads the jdbc driver
cpds.setJdbcUrl(getConnectionURL(connection));
cpds.setUser(connection.getDbUid());
cpds.setPassword(connection.getDbPwd());
cpds.setPreferredTestQuery(DEFAULT_CONN_TEST_SQL);
cpds.setIdleConnectionTestPeriod(120);
cpds.setAcquireRetryAttempts(5);
//cpds.setCheckoutTimeout(60);
ds.setDataSourceName("AdempiereDS"); if (Ini.isClient())
ds.setServerName(connection.getDbHost()); {
ds.setDatabaseName(connection.getDbName()); cpds.setInitialPoolSize(1);
ds.setUser(connection.getDbUid()); cpds.setMinPoolSize(1);
ds.setPassword(connection.getDbPwd()); cpds.setMaxPoolSize(15);
ds.setPortNumber(connection.getDbPort()); cpds.setMaxIdleTimeExcessConnections(1200);
ds.setMaxConnections(50); cpds.setMaxIdleTime(600);
ds.setInitialConnections(0); m_maxbusyconnections = 12;
}
else
{
cpds.setInitialPoolSize(10);
cpds.setMinPoolSize(5);
cpds.setMaxPoolSize(150);
cpds.setMaxIdleTimeExcessConnections(1200);
cpds.setMaxIdleTime(900);
m_maxbusyconnections = 120;
}
//new InitialContext().rebind("DataSource", source); cpds.setUnreturnedConnectionTimeout(1200);
m_ds = ds; cpds.setDebugUnreturnedConnectionStackTraces(true);
m_ds = cpds;
}
catch (Exception ex)
{
m_ds = null;
log.log(Level.SEVERE, "Could not initialise C3P0 Datasource", ex);
}
return m_ds; return m_ds;
} }

View File

@ -16,9 +16,13 @@
*****************************************************************************/ *****************************************************************************/
package org.compiere.model; package org.compiere.model;
import java.rmi.RemoteException;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.*;
import java.util.logging.*; import java.util.logging.*;
import org.compiere.db.CConnection;
import org.compiere.interfaces.Server;
import org.compiere.util.*; import org.compiere.util.*;
/** /**
@ -37,6 +41,7 @@ public class MSequence extends X_AD_Sequence
/** Log Level for Next ID Call */ /** Log Level for Next ID Call */
private static final Level LOGLEVEL = Level.ALL; private static final Level LOGLEVEL = Level.ALL;
/** /**
* Get next number for Key column = 0 is Error. * Get next number for Key column = 0 is Error.
* @param AD_Client_ID client * @param AD_Client_ID client
@ -48,6 +53,30 @@ public class MSequence extends X_AD_Sequence
{ {
if (TableName == null || TableName.length() == 0) if (TableName == null || TableName.length() == 0)
throw new IllegalArgumentException("TableName missing"); throw new IllegalArgumentException("TableName missing");
//get from server
if (DB.isRemoteObjects())
{
Server server = CConnection.get().getServer();
try
{
if (server != null)
{ // See ServerBean
int id = server.getNextID(AD_Client_ID, TableName, trxName);
s_log.finest("server => " + id);
if (id < 0)
throw new DBException("No NextID");
return id;
}
s_log.log(Level.SEVERE, "AppsServer not found - " + TableName);
}
catch (RemoteException ex)
{
s_log.log(Level.SEVERE, "AppsServer error", ex);
}
// Try locally
}
int retValue = -1; int retValue = -1;
// Check AdempiereSys // Check AdempiereSys
@ -146,7 +175,8 @@ public class MSequence extends X_AD_Sequence
pstmt = null; pstmt = null;
conn.setAutoCommit(autocommit); //jz set back conn.setAutoCommit(autocommit); //jz set back
// //
// conn.close(); if (trx == null && conn != null)
conn.close();
conn = null; conn = null;
// //
break; // EXIT break; // EXIT
@ -241,6 +271,28 @@ public class MSequence extends X_AD_Sequence
if (TableName == null || TableName.length() == 0) if (TableName == null || TableName.length() == 0)
throw new IllegalArgumentException("TableName missing"); throw new IllegalArgumentException("TableName missing");
//get from server
if (DB.isRemoteObjects())
{
Server server = CConnection.get().getServer();
try
{
if (server != null)
{ // See ServerBean
String dn = server.getDocumentNo (AD_Client_ID, TableName, trxName);
s_log.finest("Server => " + dn);
if (dn != null)
return dn;
}
s_log.log(Level.SEVERE, "AppsServer not found - " + TableName);
}
catch (RemoteException ex)
{
s_log.log(Level.SEVERE, "AppsServer error", ex);
}
}
//local
// Check AdempiereSys // Check AdempiereSys
boolean adempiereSys = Ini.isPropertyBool(Ini.P_ADEMPIERESYS); boolean adempiereSys = Ini.isPropertyBool(Ini.P_ADEMPIERESYS);
if (adempiereSys && AD_Client_ID > 11) if (adempiereSys && AD_Client_ID > 11)
@ -344,7 +396,7 @@ public class MSequence extends X_AD_Sequence
if (trx == null) if (trx == null)
{ {
conn.commit(); conn.commit();
// conn.close(); conn.close();
} }
conn = null; conn = null;
} }
@ -359,8 +411,8 @@ public class MSequence extends X_AD_Sequence
if (pstmt != null) if (pstmt != null)
pstmt.close(); pstmt.close();
pstmt = null; pstmt = null;
// if (conn != null && trx == null) if (trx == null && conn != null)
// conn.close(); conn.close();
conn = null; conn = null;
} }
catch (Exception e) catch (Exception e)
@ -398,6 +450,29 @@ public class MSequence extends X_AD_Sequence
s_log.severe ("C_DocType_ID=0"); s_log.severe ("C_DocType_ID=0");
return null; return null;
} }
//get from server
if (DB.isRemoteObjects())
{
Server server = CConnection.get().getServer();
try
{
if (server != null)
{ // See ServerBean
String dn = server.getDocumentNo (C_DocType_ID, trxName);
s_log.finest("Server => " + dn);
if (dn != null)
return dn;
}
s_log.log(Level.SEVERE, "AppsServer not found - " + C_DocType_ID);
}
catch (RemoteException ex)
{
s_log.log(Level.SEVERE, "AppsServer error", ex);
}
}
//local
MDocType dt = MDocType.get (Env.getCtx(), C_DocType_ID); // wrong for SERVER, but r/o MDocType dt = MDocType.get (Env.getCtx(), C_DocType_ID); // wrong for SERVER, but r/o
if (dt != null && !dt.isDocNoControlled()) if (dt != null && !dt.isDocNoControlled())
{ {
@ -504,7 +579,7 @@ public class MSequence extends X_AD_Sequence
if (trx == null) if (trx == null)
{ {
conn.commit(); conn.commit();
// conn.close(); conn.close();
} }
conn = null; conn = null;
} }
@ -519,8 +594,8 @@ public class MSequence extends X_AD_Sequence
if (pstmt != null) if (pstmt != null)
pstmt.close(); pstmt.close();
pstmt = null; pstmt = null;
// if (conn != null && trx == null) if (trx == null && conn != null)
// conn.close(); conn.close();
conn = null; conn = null;
} }
catch (Exception e) catch (Exception e)

View File

@ -22,9 +22,9 @@ import java.net.*;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.*;
import java.util.logging.*; import java.util.logging.*;
import javax.sql.*; import javax.sql.*;
import org.compiere.Adempiere;
import org.compiere.db.*; import org.compiere.db.*;
import org.compiere.interfaces.*; import org.compiere.interfaces.*;
@ -33,6 +33,11 @@ import org.compiere.interfaces.*;
* *
* @author Jorg Janke * @author Jorg Janke
* @version $Id: CPreparedStatement.java,v 1.3 2006/07/30 00:54:36 jjanke Exp $ * @version $Id: CPreparedStatement.java,v 1.3 2006/07/30 00:54:36 jjanke Exp $
* ---
* Modifications: Handle connections properly
* Reason : Due to changes brought in the connection pooling whereby the system
* no more relies upon abandoned connections.
* @author Ashley Ramdass (Posterita)
*/ */
public class CPreparedStatement extends CStatement implements PreparedStatement public class CPreparedStatement extends CStatement implements PreparedStatement
{ {
@ -844,6 +849,16 @@ public class CPreparedStatement extends CStatement implements PreparedStatement
pstmt.setBigDecimal(i+1, (BigDecimal)o); pstmt.setBigDecimal(i+1, (BigDecimal)o);
log.finest("#" + (i+1) + " - BigDecimal=" + o); log.finest("#" + (i+1) + " - BigDecimal=" + o);
} }
else if (o instanceof java.util.Date)
{
pstmt.setTimestamp(i+1, new Timestamp(((java.util.Date)o).getTime()));
log.finest("#" + (i+1) + " - Date=" + o);
}
else if (o instanceof java.sql.Date)
{
pstmt.setTimestamp(i+1, new Timestamp(((java.sql.Date)o).getTime()));
log.finest("#" + (i+1) + " - Date=" + o);
}
else else
throw new java.lang.UnsupportedOperationException ("Unknown Parameter Class=" + o.getClass()); throw new java.lang.UnsupportedOperationException ("Unknown Parameter Class=" + o.getClass());
} }
@ -851,16 +866,32 @@ public class CPreparedStatement extends CStatement implements PreparedStatement
catch (SQLException ex) catch (SQLException ex)
{ {
log.log(Level.SEVERE, "local", ex); log.log(Level.SEVERE, "local", ex);
if (pstmt != null)
{
try try
{ {
if (pstmt != null)
pstmt.close(); pstmt.close();
pstmt = null;
} }
catch (SQLException ex1) catch (Exception e)
{ {
log.log(Level.SEVERE, "Could not close prepared statement", e);
} }
} }
if (conn != null && p_vo.getTrxName() == null)
{
try
{
conn.close();
}
catch (Exception e)
{
log.log(Level.SEVERE, "Could not close connection", e);
}
}
pstmt = null;
}
return pstmt; return pstmt;
} // local_getPreparedStatement } // local_getPreparedStatement
@ -969,6 +1000,16 @@ public class CPreparedStatement extends CStatement implements PreparedStatement
pstmt.setBigDecimal(i+1, (BigDecimal)o); pstmt.setBigDecimal(i+1, (BigDecimal)o);
log.finest("#" + (i+1) + " - BigDecimal=" + o); log.finest("#" + (i+1) + " - BigDecimal=" + o);
} }
else if (o instanceof java.util.Date)
{
pstmt.setTimestamp(i+1, new Timestamp(((java.util.Date)o).getTime()));
log.finest("#" + (i+1) + " - Date=" + o);
}
else if (o instanceof java.sql.Date)
{
pstmt.setTimestamp(i+1, new Timestamp(((java.sql.Date)o).getTime()));
log.finest("#" + (i+1) + " - Date=" + o);
}
else else
throw new java.lang.UnsupportedOperationException ("Unknown Parameter Class=" + o.getClass()); throw new java.lang.UnsupportedOperationException ("Unknown Parameter Class=" + o.getClass());
} }
@ -976,25 +1017,12 @@ public class CPreparedStatement extends CStatement implements PreparedStatement
ResultSet rs = pstmt.executeQuery(); ResultSet rs = pstmt.executeQuery();
rowSet = CCachedRowSet.getRowSet(rs); rowSet = CCachedRowSet.getRowSet(rs);
rs.close(); rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception ex) catch (Exception ex)
{ {
log.log(Level.SEVERE, p_vo.toString(), ex); log.log(Level.SEVERE, p_vo.toString(), ex);
throw new RuntimeException (ex); throw new RuntimeException (ex);
} }
// Close Cursor
try
{
if (pstmt != null)
pstmt.close();
pstmt = null;
}
catch (Exception e)
{
log.log(Level.SEVERE, "close", e);
}
return rowSet; return rowSet;
} // local_getRowSet } // local_getRowSet
@ -1022,11 +1050,23 @@ public class CPreparedStatement extends CStatement implements PreparedStatement
log.log(Level.SEVERE, p_vo.toString(), ex); log.log(Level.SEVERE, p_vo.toString(), ex);
throw new RuntimeException (ex); throw new RuntimeException (ex);
} }
finally { finally
if (pstmt != null) { {
try { if (pstmt != null)
{
try
{
Connection conn = pstmt.getConnection();
pstmt.close(); pstmt.close();
} catch (SQLException e) {} if (p_vo.getTrxName() == null && !conn.isClosed())
{
conn.close();
}
}
catch (SQLException e)
{
log.log(Level.SEVERE, e.getMessage(), e);
}
pstmt = null; pstmt = null;
} }
} }

View File

@ -21,7 +21,6 @@ import java.util.logging.*;
import javax.sql.*; import javax.sql.*;
import org.compiere.Adempiere;
import org.compiere.db.*; import org.compiere.db.*;
import org.compiere.interfaces.*; import org.compiere.interfaces.*;
@ -30,6 +29,12 @@ import org.compiere.interfaces.*;
* *
* @author Jorg Janke * @author Jorg Janke
* @version $Id: CStatement.java,v 1.3 2006/07/30 00:54:36 jjanke Exp $ * @version $Id: CStatement.java,v 1.3 2006/07/30 00:54:36 jjanke Exp $
* ---
* Modifications: Handle connections properly
* Close the associated connection when the statement is closed
* Reason : Due to changes brought in the connection pooling whereby the system
* no more relies upon abandoned connections.
* @author Ashley Ramdass (Posterita)
*/ */
public class CStatement implements Statement public class CStatement implements Statement
{ {
@ -743,7 +748,15 @@ public class CStatement implements Statement
public void close () throws SQLException public void close () throws SQLException
{ {
if (p_stmt != null) if (p_stmt != null)
{
Connection conn = p_stmt.getConnection();
p_stmt.close(); p_stmt.close();
if (!conn.isClosed() && conn.getAutoCommit())
{
conn.close();
}
}
} // close } // close
/************************************************************************* /*************************************************************************
@ -770,13 +783,23 @@ public class CStatement implements Statement
log.log(Level.SEVERE, p_vo.toString(), ex); log.log(Level.SEVERE, p_vo.toString(), ex);
throw new RuntimeException (ex); throw new RuntimeException (ex);
} }
finally { finally
{
if (pstmt != null) if (pstmt != null)
{ {
try try
{ {
Connection conn = pstmt.getConnection();
pstmt.close(); pstmt.close();
} catch (SQLException e){} if (p_vo.getTrxName() == null && !conn.isClosed())
{
conn.close();
}
}
catch (SQLException e)
{
log.log(Level.SEVERE, e.getMessage(), e);
}
pstmt = null; pstmt = null;
} }
} }
@ -811,14 +834,29 @@ public class CStatement implements Statement
catch (SQLException ex) catch (SQLException ex)
{ {
log.log(Level.SEVERE, "local", ex); log.log(Level.SEVERE, "local", ex);
if (stmt != null)
{
try try
{ {
if (stmt != null)
stmt.close(); stmt.close();
}
catch (Exception e)
{
log.log(Level.SEVERE, "Could not close statement", e);
}
stmt = null; stmt = null;
} }
catch (SQLException ex1)
if (conn != null && p_vo.getTrxName() == null)
{ {
try
{
conn.close();
}
catch (Exception e)
{
log.log(Level.SEVERE, "Could not close connection", e);
}
} }
} }
return stmt; return stmt;
@ -926,17 +964,6 @@ public class CStatement implements Statement
log.log(Level.SEVERE, p_vo.toString(), ex); log.log(Level.SEVERE, p_vo.toString(), ex);
throw new RuntimeException (ex); throw new RuntimeException (ex);
} }
// Close Cursor
try
{
if (pstmt != null)
pstmt.close();
pstmt = null;
}
catch (Exception e)
{
log.log(Level.SEVERE, "close pstmt", e);
}
return rowSet; return rowSet;
} // local_getRowSet } // local_getRowSet

View File

@ -23,9 +23,9 @@ import java.sql.*;
import java.text.*; import java.text.*;
import java.util.*; import java.util.*;
import java.util.logging.*; import java.util.logging.*;
import javax.sql.*; import javax.sql.*;
import javax.swing.*; import javax.swing.*;
import oracle.jdbc.*;
// //
import org.compiere.*; import org.compiere.*;
import org.compiere.db.*; import org.compiere.db.*;
@ -43,6 +43,11 @@ import org.compiere.process.*;
* *
* @author Jorg Janke * @author Jorg Janke
* @version $Id: DB.java,v 1.8 2006/10/09 00:22:29 jjanke Exp $ * @version $Id: DB.java,v 1.8 2006/10/09 00:22:29 jjanke Exp $
* ---
* Modifications: removed static references to database connection and instead always
* get a new connection from database pool manager which manages all connections
* set rw/ro properties for the connection accordingly.
* @author Ashley Ramdass (Posterita)
*/ */
public final class DB public final class DB
{ {
@ -83,34 +88,28 @@ public final class DB
log.info("Role"); log.info("Role");
String sql = "SELECT * FROM AD_Role"; String sql = "SELECT * FROM AD_Role";
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
pstmt = DB.prepareStatement (sql, null); pstmt = DB.prepareStatement (sql, null);
ResultSet rs = pstmt.executeQuery (); rs = pstmt.executeQuery ();
while (rs.next ()) while (rs.next ())
{ {
MRole role = new MRole (ctx, rs, null); MRole role = new MRole (ctx, rs, null);
role.updateAccessRecords(); role.updateAccessRecords();
} }
rs.close ();
pstmt.close ();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
log.log(Level.SEVERE, "(1)", e); log.log(Level.SEVERE, "(1)", e);
} }
try finally
{ {
if (pstmt != null) close(rs);
pstmt.close (); close(pstmt);
rs= null;
pstmt = null; pstmt = null;
} }
catch (Exception e)
{
pstmt = null;
}
// Release Specif stuff & Print Format // Release Specif stuff & Print Format
try try
{ {
@ -233,9 +232,6 @@ public final class DB
synchronized(s_ccLock) synchronized(s_ccLock)
{ {
s_cc = cc; s_cc = cc;
s_connections = null;
s_connectionRW = null;
s_connectionID = null;
} }
if ( isRemoteObjects() == false) if ( isRemoteObjects() == false)
s_cc.setDataSource(); s_cc.setDataSource();
@ -261,12 +257,29 @@ public final class DB
boolean success =false; boolean success =false;
try try
{ {
success = getConnectionRW() != null; Connection connRW = getConnectionRW();
if (success) success = getConnectionRO() != null; if (connRW != null)
if (success) success = getConnectionID() != null;
s_cc.readInfo(getConnectionRW());
} catch (Exception e)
{ {
s_cc.readInfo(connRW);
connRW.close();
}
Connection connRO = getConnectionRO();
if (connRO != null)
{
connRO.close();
}
Connection connID = getConnectionID();
if (connID != null)
{
connID.close();
}
success = ((connRW != null) && (connRO != null) && (connID != null));
}
catch (Exception e)
{
log.log(Level.SEVERE, "Could not connect to DB", e);
success = false; success = false;
} }
return success; return success;
@ -307,7 +320,12 @@ public final class DB
eb = null; // don't reset eb = null; // don't reset
try try
{ {
success = getConnectionRW(createNew) != null; // try to get a connection Connection conn = getConnectionRW(createNew); // try to get a connection
if (conn != null)
{
conn.close();
}
success = (conn != null);
} }
catch (Exception e) catch (Exception e)
{ {
@ -334,49 +352,7 @@ public final class DB
*/ */
public static Connection getConnectionRW (boolean createNew) public static Connection getConnectionRW (boolean createNew)
{ {
//wan profile return createConnection(true, false, Connection.TRANSACTION_READ_COMMITTED);
if (CConnection.get().isRMIoverHTTP()) return null;
// check health of connection
try
{
if (s_connectionRW == null)
;
else if (s_connectionRW.isClosed())
{
log.finest("Closed");
s_connectionRW = null;
}
else if (s_connectionRW instanceof OracleConnection && ((OracleConnection)s_connectionRW).pingDatabase(1) < 0)
{
log.warning("No ping");
s_connectionRW = null;
}
else
{
if (s_connectionRW.getTransactionIsolation() != Connection.TRANSACTION_READ_COMMITTED)
s_connectionRW.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
}
}
catch (Exception e)
{
s_connectionRW = null;
}
// Get new
if (s_connectionRW == null)
{
if (createNew)
{
s_connectionRW = s_cc.getConnection (true, Connection.TRANSACTION_READ_COMMITTED);
log.finest("Con=" + s_connectionRW);
}
}
if (s_connectionRW == null && createNew)
throw new UnsupportedOperationException("No DBConnection");
//
// System.err.println ("DB.getConnectionRW - " + s_connectionRW);
// Trace.printStack();
return s_connectionRW;
} // getConnectionRW } // getConnectionRW
/** /**
@ -386,29 +362,7 @@ public final class DB
*/ */
public static Connection getConnectionID () public static Connection getConnectionID ()
{ {
//wan profile return createConnection(false, false, Connection.TRANSACTION_READ_COMMITTED);
if (CConnection.get().isRMIoverHTTP()) return null;
if (s_connectionID != null)
{
try
{
if (s_connectionID.isClosed())
s_connectionID = null;
}
catch (Exception e)
{
s_connectionID = null;
}
}
if (s_connectionID == null)
{
s_connectionID = s_cc.getConnection (false, Connection.TRANSACTION_READ_COMMITTED);
}
if (s_connectionID == null)
throw new UnsupportedOperationException("No DBConnection");
log.log(Level.ALL, s_connectionID.toString());
return s_connectionID;
} // getConnectionID } // getConnectionID
/** /**
@ -417,75 +371,7 @@ public final class DB
*/ */
public static Connection getConnectionRO () public static Connection getConnectionRO ()
{ {
//wan profile return createConnection(true, true, Connection.TRANSACTION_READ_COMMITTED); // see below
if (CConnection.get().isRMIoverHTTP()) return null;
try
{
synchronized(s_ccLock)
{
if (s_connections == null)
s_connections = createConnections (Connection.TRANSACTION_READ_COMMITTED); // see below
}
}
catch (Exception e)
{
log.log(Level.SEVERE, "RO", e);
}
// check health of connection
int pos = s_conCount++;
int connectionNo = pos % s_conCacheSize;
Connection connection = s_connections[connectionNo];
try
{
if (connection == null)
;
else if (connection.isClosed())
{
// RowSet.close also closes connection!
// System.out.println("DB.getConnectionRO - closed #" + connectionNo);
connection = null;
}
else if (connection instanceof OracleConnection && ((OracleConnection)connection).pingDatabase(1) < 0)
{
log.warning("No ping #" + connectionNo);
connection = null;
}
else
{
if (!connection.isReadOnly())
connection.setReadOnly(true);
if (connection.getTransactionIsolation() != Connection.TRANSACTION_READ_COMMITTED)
connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
}
}
catch (Exception e)
{
log.severe("#" + connectionNo + " - " + e.toString());
connection = null;
}
// Get new
if (connection == null)
{
log.finest("Replacing connection #" + connectionNo);
connection = s_cc.getConnection (true, Connection.TRANSACTION_READ_COMMITTED); // see above
try
{
if (connection != null)
connection.setReadOnly(true);
}
catch (Exception e)
{
log.severe("Cannot set to R/O - " + e);
}
s_connections[connectionNo] = connection;
}
if (connection == null)
throw new UnsupportedOperationException("DB.getConnectionRO - @NoDBConnection@");
log.log(Level.ALL, "#" + connectionNo + " - " + connection);
// System.err.println ("DB.getConnectionRO - " + connection);
return connection;
} // getConnectionRO } // getConnectionRO
/** /**
@ -521,33 +407,40 @@ public final class DB
} // createConnection } // createConnection
/** /**
* Create new set of r/o Connections. * Create new Connection.
* R/O connection might not be supported by DB * The connection must be closed explicitly by the application
* *
* @param autoCommit auto commit
* @param trxLevel - Connection.TRANSACTION_READ_UNCOMMITTED, Connection.TRANSACTION_READ_COMMITTED, Connection.TRANSACTION_REPEATABLE_READ, or Connection.TRANSACTION_READ_COMMITTED. * @param trxLevel - Connection.TRANSACTION_READ_UNCOMMITTED, Connection.TRANSACTION_READ_COMMITTED, Connection.TRANSACTION_REPEATABLE_READ, or Connection.TRANSACTION_READ_COMMITTED.
* @return Array of Connections (size based on s_conCacheSize) * @return Connection connection
*/ */
private static Connection[] createConnections (int trxLevel) public static Connection createConnection (boolean autoCommit, boolean readOnly, int trxLevel)
{
//wan profile
if (CConnection.get().isRMIoverHTTP()) return null;
Connection conn = s_cc.getConnection (autoCommit, trxLevel);
if (conn != null)
{ {
log.finest("(" + s_conCacheSize + ") " + s_cc.getConnectionURL()
+ ", UserID=" + s_cc.getDbUid()
+ ", TrxLevel=" + CConnection.getTransactionIsolationInfo(trxLevel));
Connection cons[] = new Connection[s_conCacheSize];
try try
{ {
for (int i = 0; i < s_conCacheSize; i++) conn.setReadOnly(readOnly);
}
catch (SQLException ex)
{ {
cons[i] = s_cc.getConnection (true, trxLevel); // auto commit conn = null;
if (cons[i] == null) log.log(Level.SEVERE, ex.getMessage(), ex);
log.warning("Connection is NULL"); // don't use log
} }
} }
catch (Exception e)
if (conn == null)
{ {
log.severe(e.getMessage()); throw new IllegalStateException("DB.getConnectionRO - @NoDBConnection@");
} }
return cons;
} // createConnections return conn;
} // createConnection
/** /**
* Get Database Driver. * Get Database Driver.
@ -618,23 +511,30 @@ public final class DB
*/ */
public static boolean isDatabaseOK (Properties ctx) public static boolean isDatabaseOK (Properties ctx)
{ {
// Check Version // Check Version
String version = "?"; String version = "?";
String sql = "SELECT Version FROM AD_System"; String sql = "SELECT Version FROM AD_System";
PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
PreparedStatement pstmt = prepareStatement(sql, null); pstmt = prepareStatement(sql, null);
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
version = rs.getString(1); version = rs.getString(1);
rs.close();
pstmt.close();
} }
catch (SQLException e) catch (SQLException e)
{ {
log.log(Level.SEVERE, "Problem with AD_System Table - Run system.sql script - " + e.toString()); log.log(Level.SEVERE, "Problem with AD_System Table - Run system.sql script - " + e.toString());
return false; return false;
} }
finally
{
close(rs);
close(pstmt);
rs= null;
pstmt = null;
}
log.info("DB_Version=" + version); log.info("DB_Version=" + version);
// Identical DB version // Identical DB version
if (Adempiere.DB_VERSION.equals(version)) if (Adempiere.DB_VERSION.equals(version))
@ -665,56 +565,8 @@ public final class DB
*/ */
public static void closeTarget() public static void closeTarget()
{ {
boolean closed = false; boolean closed = false;
// RO connection
if (s_connections != null)
{
for (int i = 0; i < s_conCacheSize; i++)
{
try
{
if (s_connections[i] != null)
{
closed = true;
s_connections[i].close();
}
}
catch (SQLException e)
{
log.warning("#" + i + " - " + e.getMessage());
}
s_connections[i] = null;
}
}
s_connections = null;
// RW connection
try
{
if (s_connectionRW != null)
{
closed = true;
s_connectionRW.close();
}
}
catch (SQLException e)
{
log.log(Level.SEVERE, "R/W", e);
}
s_connectionRW = null;
//ID Connection
try
{
if (s_connectionID != null)
{
s_connectionID.close();
}
} catch (SQLException e)
{
log.log(Level.SEVERE, "Id", e);
}
s_connectionID = null;
// CConnection // CConnection
if (s_cc != null) if (s_cc != null)
@ -1080,18 +932,28 @@ public final class DB
* @return true if not needed or success * @return true if not needed or success
* @throws SQLException * @throws SQLException
*/ */
public static boolean commit (boolean throwException, String trxName) throws SQLException public static boolean commit (boolean throwException, String trxName) throws SQLException,IllegalStateException
{ {
// Not on transaction scope, Connection are thus auto commit
if (trxName == null)
{
return true;
}
try try
{ {
Connection conn = null; Trx trx = Trx.get(trxName, false);
Trx trx = trxName == null ? null : Trx.get(trxName, true);
if (trx != null) if (trx != null)
return trx.commit(true); return trx.commit(true);
if (throwException)
{
throw new IllegalStateException("Could not load transation with identifier: " + trxName);
}
else else
conn = DB.getConnectionRW (); {
if (conn != null && !conn.getAutoCommit()) return false;
conn.commit(); }
} }
catch (SQLException e) catch (SQLException e)
{ {
@ -1100,7 +962,6 @@ public final class DB
throw e; throw e;
return false; return false;
} }
return true;
} // commit } // commit
/** /**
@ -1166,17 +1027,15 @@ public final class DB
{ {
int retValue = -1; int retValue = -1;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
pstmt = prepareStatement(sql, trxName); pstmt = prepareStatement(sql, trxName);
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
retValue = rs.getInt(1); retValue = rs.getInt(1);
else else
log.fine("No Value " + sql); log.fine("No Value " + sql);
rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1184,13 +1043,9 @@ public final class DB
} }
finally finally
{ {
try close(rs);
{ close(pstmt);
if (pstmt != null) rs= null;
pstmt.close ();
}
catch (Exception e)
{}
pstmt = null; pstmt = null;
} }
return retValue; return retValue;
@ -1207,18 +1062,16 @@ public final class DB
{ {
int retValue = -1; int retValue = -1;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
pstmt = prepareStatement(sql, trxName); pstmt = prepareStatement(sql, trxName);
pstmt.setInt(1, int_param1); pstmt.setInt(1, int_param1);
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
retValue = rs.getInt(1); retValue = rs.getInt(1);
else else
log.config("No Value " + sql + " - Param1=" + int_param1); log.config("No Value " + sql + " - Param1=" + int_param1);
rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1226,13 +1079,9 @@ public final class DB
} }
finally finally
{ {
try close(rs);
{ close(pstmt);
if (pstmt != null) rs= null;
pstmt.close ();
}
catch (Exception e)
{}
pstmt = null; pstmt = null;
} }
return retValue; return retValue;
@ -1250,20 +1099,18 @@ public final class DB
{ {
int retValue = -1; int retValue = -1;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
pstmt = prepareStatement(sql, trxName); pstmt = prepareStatement(sql, trxName);
pstmt.setInt(1, int_param1); pstmt.setInt(1, int_param1);
pstmt.setInt(2, int_param2); pstmt.setInt(2, int_param2);
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
retValue = rs.getInt(1); retValue = rs.getInt(1);
else else
log.info("No Value " + sql log.info("No Value " + sql
+ " - Param1=" + int_param1 + ",Param2=" + int_param2); + " - Param1=" + int_param1 + ",Param2=" + int_param2);
rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1272,13 +1119,9 @@ public final class DB
} }
finally finally
{ {
try close(rs);
{ close(pstmt);
if (pstmt != null) rs= null;
pstmt.close ();
}
catch (Exception e)
{}
pstmt = null; pstmt = null;
} }
return retValue; return retValue;
@ -1295,18 +1138,16 @@ public final class DB
{ {
int retValue = -1; int retValue = -1;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
pstmt = prepareStatement(sql, trxName); pstmt = prepareStatement(sql, trxName);
pstmt.setString(1, str_param1); pstmt.setString(1, str_param1);
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
retValue = rs.getInt(1); retValue = rs.getInt(1);
else else
log.info("No Value " + sql + " - Param1=" + str_param1); log.info("No Value " + sql + " - Param1=" + str_param1);
rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1314,13 +1155,9 @@ public final class DB
} }
finally finally
{ {
try close(rs);
{ close(pstmt);
if (pstmt != null) rs= null;
pstmt.close ();
}
catch (Exception e)
{}
pstmt = null; pstmt = null;
} }
return retValue; return retValue;
@ -1338,19 +1175,17 @@ public final class DB
{ {
int retValue = -1; int retValue = -1;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
pstmt = prepareStatement(sql, trxName); pstmt = prepareStatement(sql, trxName);
pstmt.setInt(1, int_param1); pstmt.setInt(1, int_param1);
pstmt.setString(2, s_param2); pstmt.setString(2, s_param2);
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
retValue = rs.getInt(1); retValue = rs.getInt(1);
else else
log.info("No Value: " + sql + " - Param1=" + int_param1 + ",Param2=" + s_param2); log.info("No Value: " + sql + " - Param1=" + int_param1 + ",Param2=" + s_param2);
rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1358,13 +1193,9 @@ public final class DB
} }
finally finally
{ {
try close(rs);
{ close(pstmt);
if (pstmt != null) rs= null;
pstmt.close ();
}
catch (Exception e)
{}
pstmt = null; pstmt = null;
} }
return retValue; return retValue;
@ -1381,18 +1212,16 @@ public final class DB
{ {
String retValue = null; String retValue = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
pstmt = prepareStatement(sql, trxName); pstmt = prepareStatement(sql, trxName);
pstmt.setInt(1, int_param1); pstmt.setInt(1, int_param1);
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
retValue = rs.getString(1); retValue = rs.getString(1);
else else
log.info("No Value " + sql + " - Param1=" + int_param1); log.info("No Value " + sql + " - Param1=" + int_param1);
rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1400,13 +1229,9 @@ public final class DB
} }
finally finally
{ {
try close(rs);
{ close(pstmt);
if (pstmt != null) rs= null;
pstmt.close ();
}
catch (Exception e)
{}
pstmt = null; pstmt = null;
} }
return retValue; return retValue;
@ -1423,18 +1248,16 @@ public final class DB
{ {
BigDecimal retValue = null; BigDecimal retValue = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
pstmt = prepareStatement(sql, trxName); pstmt = prepareStatement(sql, trxName);
pstmt.setInt(1, int_param1); pstmt.setInt(1, int_param1);
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
if (rs.next()) if (rs.next())
retValue = rs.getBigDecimal(1); retValue = rs.getBigDecimal(1);
else else
log.info("No Value " + sql + " - Param1=" + int_param1); log.info("No Value " + sql + " - Param1=" + int_param1);
rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1442,19 +1265,14 @@ public final class DB
} }
finally finally
{ {
try close(rs);
{ close(pstmt);
if (pstmt != null) rs= null;
pstmt.close ();
}
catch (Exception e)
{}
pstmt = null; pstmt = null;
} }
return retValue; return retValue;
} // getSQLValueBD } // getSQLValueBD
/** /**
* Get Array of Key Name Pairs * Get Array of Key Name Pairs
* @param sql select with id / name as first / second column * @param sql select with id / name as first / second column
@ -1464,31 +1282,26 @@ public final class DB
public static KeyNamePair[] getKeyNamePairs(String sql, boolean optional) public static KeyNamePair[] getKeyNamePairs(String sql, boolean optional)
{ {
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
ArrayList<KeyNamePair> list = new ArrayList<KeyNamePair>(); ArrayList<KeyNamePair> list = new ArrayList<KeyNamePair>();
if (optional) if (optional)
list.add (new KeyNamePair(-1, "")); list.add (new KeyNamePair(-1, ""));
try try
{ {
pstmt = DB.prepareStatement(sql, null); pstmt = DB.prepareStatement(sql, null);
ResultSet rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
while (rs.next()) while (rs.next())
list.add(new KeyNamePair(rs.getInt(1), rs.getString(2))); list.add(new KeyNamePair(rs.getInt(1), rs.getString(2)));
rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
log.log(Level.SEVERE, sql, e); log.log(Level.SEVERE, sql, e);
} }
try finally
{
if (pstmt != null)
pstmt.close();
pstmt = null;
}
catch (Exception e)
{ {
close(rs);
close(pstmt);
rs= null;
pstmt = null; pstmt = null;
} }
KeyNamePair[] retValue = new KeyNamePair[list.size()]; KeyNamePair[] retValue = new KeyNamePair[list.size()];
@ -1521,15 +1334,13 @@ public final class DB
String sql = "SELECT IsSOTrx FROM " + TableName String sql = "SELECT IsSOTrx FROM " + TableName
+ " WHERE " + whereClause; + " WHERE " + whereClause;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null;
try try
{ {
pstmt = DB.prepareStatement (sql, null); pstmt = DB.prepareStatement (sql, null);
ResultSet rs = pstmt.executeQuery (); rs = pstmt.executeQuery ();
if (rs.next ()) if (rs.next ())
isSOTrx = "Y".equals(rs.getString(1)); isSOTrx = "Y".equals(rs.getString(1));
rs.close ();
pstmt.close ();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1541,45 +1352,36 @@ public final class DB
+ " l WHERE h." + hdr + "_ID=l." + hdr + "_ID AND " + " l WHERE h." + hdr + "_ID=l." + hdr + "_ID AND "
+ whereClause + ")"; + whereClause + ")";
PreparedStatement pstmt2 = null; PreparedStatement pstmt2 = null;
ResultSet rs2 = null;
try try
{ {
pstmt2 = DB.prepareStatement (sql, null); pstmt2 = DB.prepareStatement (sql, null);
ResultSet rs2 = pstmt2.executeQuery (); rs2 = pstmt2.executeQuery ();
if (rs2.next ()) if (rs2.next ())
isSOTrx = "Y".equals(rs2.getString(1)); isSOTrx = "Y".equals(rs2.getString(1));
rs2.close ();
pstmt2.close ();
pstmt2 = null;
} }
catch (Exception ee) catch (Exception ee)
{ {
log.finest(sql + " - " + e.getMessage()); log.log(Level.FINEST, sql + " - " + e.getMessage(), ee);
} }
try finally
{ {
if (pstmt2 != null) close(rs2);
pstmt2.close (); close(pstmt2);
pstmt2 = null; rs= null;
} pstmt = null;
catch (Exception ee)
{
pstmt2 = null;
} }
} }
else else
{ {
log.finest(TableName + " - No SOTrx"); log.log(Level.FINEST, TableName + " - No SOTrx", e);
// log.finest(sql + " - " + e.getMessage());
} }
} }
try finally
{
if (pstmt != null)
pstmt.close ();
pstmt = null;
}
catch (Exception e)
{ {
close(rs);
close(pstmt);
rs= null;
pstmt = null; pstmt = null;
} }
return isSOTrx; return isSOTrx;
@ -1611,31 +1413,7 @@ public final class DB
*/ */
public static int getNextID (int AD_Client_ID, String TableName, String trxName) public static int getNextID (int AD_Client_ID, String TableName, String trxName)
{ {
if (isRemoteObjects()) return MSequence.getNextID (AD_Client_ID, TableName, trxName);
{
Server server = CConnection.get().getServer();
try
{
if (server != null)
{ // See ServerBean
int id = server.getNextID(AD_Client_ID, TableName, trxName);
log.finest("server => " + id);
if (id < 0)
throw new DBException("No NextID");
return id;
}
log.log(Level.SEVERE, "AppsServer not found - " + TableName);
}
catch (RemoteException ex)
{
log.log(Level.SEVERE, "AppsServer error", ex);
}
// Try locally
}
int id = MSequence.getNextID (AD_Client_ID, TableName, trxName); // tries 3 times
// if (id <= 0)
// throw new DBException("No NextID (" + id + ")");
return id;
} // getNextID } // getNextID
/** /**
@ -1646,32 +1424,7 @@ public final class DB
*/ */
public static String getDocumentNo(int C_DocType_ID, String trxName) public static String getDocumentNo(int C_DocType_ID, String trxName)
{ {
if (isRemoteObjects()) return MSequence.getDocumentNo (C_DocType_ID, trxName);
{
Server server = CConnection.get().getServer();
try
{
if (server != null)
{ // See ServerBean
String dn = server.getDocumentNo (C_DocType_ID, trxName);
log.finest("Server => " + dn);
if (dn != null)
return dn;
}
log.log(Level.SEVERE, "AppsServer not found - " + C_DocType_ID);
}
catch (RemoteException ex)
{
log.log(Level.SEVERE, "AppsServer error", ex);
}
}
// fallback
String dn = MSequence.getDocumentNo (C_DocType_ID, trxName);
if (dn == null) // try again
dn = MSequence.getDocumentNo (C_DocType_ID, trxName);
// if (dn == null)
// throw new DBException ("No DocumentNo");
return dn;
} // getDocumentNo } // getDocumentNo
@ -1684,29 +1437,7 @@ public final class DB
*/ */
public static String getDocumentNo (int AD_Client_ID, String TableName, String trxName) public static String getDocumentNo (int AD_Client_ID, String TableName, String trxName)
{ {
if (isRemoteObjects())
{
Server server = CConnection.get().getServer();
try
{
if (server != null)
{ // See ServerBean
String dn = server.getDocumentNo (AD_Client_ID, TableName, trxName);
log.finest("Server => " + dn);
if (dn != null)
return dn;
}
log.log(Level.SEVERE, "AppsServer not found - " + TableName);
}
catch (RemoteException ex)
{
log.log(Level.SEVERE, "AppsServer error", ex);
}
}
// fallback
String dn = MSequence.getDocumentNo (AD_Client_ID, TableName, trxName); String dn = MSequence.getDocumentNo (AD_Client_ID, TableName, trxName);
if (dn == null) // try again
dn = MSequence.getDocumentNo (AD_Client_ID, TableName, trxName);
if (dn == null) if (dn == null)
throw new DBException ("No DocumentNo"); throw new DBException ("No DocumentNo");
return dn; return dn;
@ -1898,6 +1629,30 @@ public final class DB
return out.toString(); return out.toString();
} // TO_STRING } // TO_STRING
/**
* convenient method to close result set
* @param rs
*/
public static void close( ResultSet rs) {
try {
if (rs!=null) rs.close();
} catch (SQLException e) {
;
}
}
/**
* convenient method to close statement
* @param st
*/
public static void close( Statement st) {
try {
if (st!=null) st.close();
} catch (SQLException e) {
;
}
}
/** Quote */ /** Quote */
private static final char QUOTE = '\''; private static final char QUOTE = '\'';