BF [ 1874419 ] JDBC Statement not close in a finally block

- implemented close using finalization, now much more stable even there are leak connections!
This commit is contained in:
Heng Sin Low 2008-02-16 03:09:40 +00:00
parent 5c448f6834
commit 5569168787
5 changed files with 60 additions and 38 deletions

View File

@ -570,7 +570,7 @@ public class DB_Oracle implements AdempiereDatabase
cpds.setMaxPoolSize(15); cpds.setMaxPoolSize(15);
cpds.setMaxIdleTimeExcessConnections(1200); cpds.setMaxIdleTimeExcessConnections(1200);
cpds.setMaxIdleTime(900); cpds.setMaxIdleTime(900);
m_maxbusyconnections = 12; m_maxbusyconnections = 10;
} }
else else
{ {
@ -668,10 +668,12 @@ public class DB_Oracle implements AdempiereDatabase
try try
{ {
if (conn != null) { if (conn != null) {
int numConnections = m_ds.getNumBusyConnections(); int numConnections = m_ds.getNumBusyConnections();
if(numConnections >= m_maxbusyconnections ) if(numConnections >= m_maxbusyconnections && m_maxbusyconnections > 0)
{ {
log.warning(getStatus()); log.warning(getStatus());
//hengsin: make a best effort to reclaim leak connection
Runtime.getRuntime().runFinalization();
} }
} }
} }

View File

@ -505,13 +505,24 @@ public class DB_PostgreSQL implements AdempiereDatabase
getDataSource(connection); getDataSource(connection);
// //
Connection conn = m_ds.getConnection(); Connection conn = m_ds.getConnection();
ComboPooledDataSource cpds = (ComboPooledDataSource)m_ds; if (conn != null) {
//System.out.println("Num Connections: " + cpds.getNumConnections() + ", Busy Connections: " //
// + cpds.getNumBusyConnections()); conn.setAutoCommit(autoCommit);
// Connection conn = getDriverConnection(connection); conn.setTransactionIsolation(transactionIsolation);
//
conn.setAutoCommit(autoCommit); try
conn.setTransactionIsolation(transactionIsolation); {
int numConnections = m_ds.getNumBusyConnections();
if(numConnections >= m_maxbusyconnections && m_maxbusyconnections > 0)
{
log.warning(getStatus());
//hengsin: make a best effort to reclaim leak connection
Runtime.getRuntime().runFinalization();
}
}
catch (Exception ex)
{}
}
return conn; return conn;
} // getCachedConnection } // getCachedConnection
@ -551,7 +562,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
cpds.setMaxPoolSize(15); cpds.setMaxPoolSize(15);
cpds.setMaxIdleTimeExcessConnections(1200); cpds.setMaxIdleTimeExcessConnections(1200);
cpds.setMaxIdleTime(900); cpds.setMaxIdleTime(900);
m_maxbusyconnections = 12; m_maxbusyconnections = 10;
} }
else else
{ {

View File

@ -81,14 +81,14 @@ public class CCallableStatement extends CPreparedStatement implements CallableSt
if (trx != null) if (trx != null)
{ {
conn = trx.getConnection(); conn = trx.getConnection();
useTransactionConnection = true;
} }
else else
{ {
if (p_vo.getResultSetConcurrency() == ResultSet.CONCUR_UPDATABLE) if (p_vo.getResultSetConcurrency() == ResultSet.CONCUR_UPDATABLE)
conn = DB.getConnectionRW (); m_conn = DB.getConnectionRW ();
else else
conn = DB.getConnectionRO(); m_conn = DB.getConnectionRO();
conn = m_conn;
} }
if (conn == null) if (conn == null)
throw new DBException("No Connection"); throw new DBException("No Connection");

View File

@ -78,14 +78,14 @@ public class CPreparedStatement extends CStatement implements PreparedStatement
if (trx != null) if (trx != null)
{ {
conn = trx.getConnection(); conn = trx.getConnection();
useTransactionConnection = true;
} }
else else
{ {
if (p_vo.getResultSetConcurrency() == ResultSet.CONCUR_UPDATABLE) if (p_vo.getResultSetConcurrency() == ResultSet.CONCUR_UPDATABLE)
conn = DB.getConnectionRW (); m_conn = DB.getConnectionRW ();
else else
conn = DB.getConnectionRO(); m_conn = DB.getConnectionRO();
conn = m_conn;
} }
if (conn == null) if (conn == null)
throw new DBException("No Connection"); throw new DBException("No Connection");

View File

@ -38,7 +38,7 @@ import org.compiere.interfaces.*;
*/ */
public class CStatement implements Statement public class CStatement implements Statement
{ {
protected boolean useTransactionConnection = false; protected Connection m_conn = null;
private boolean close = false; private boolean close = false;
@ -74,14 +74,14 @@ public class CStatement implements Statement
if (trx != null) if (trx != null)
{ {
conn = trx.getConnection(); conn = trx.getConnection();
useTransactionConnection = true;
} }
else else
{ {
if (p_vo.getResultSetConcurrency() == ResultSet.CONCUR_UPDATABLE) if (p_vo.getResultSetConcurrency() == ResultSet.CONCUR_UPDATABLE)
conn = DB.getConnectionRW (); m_conn = DB.getConnectionRW ();
else else
conn = DB.getConnectionRO(); m_conn = DB.getConnectionRO();
conn = m_conn;
} }
if (conn == null) if (conn == null)
throw new DBException("No Connection"); throw new DBException("No Connection");
@ -739,17 +739,24 @@ public class CStatement implements Statement
*/ */
public void close () throws SQLException public void close () throws SQLException
{ {
if (p_stmt != null) try {
{ if (p_stmt != null)
Connection conn = p_stmt.getConnection(); {
p_stmt.close(); p_stmt.close();
}
if (!close && !useTransactionConnection) } finally {
{ if (m_conn != null)
conn.close(); {
} try
} {
close = true; m_conn.close();
}
catch (Exception e)
{}
}
m_conn = null;
close = true;
}
} // close } // close
/** /**
@ -871,12 +878,14 @@ public class CStatement implements Statement
public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException{return null;} public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException{return null;}
/** @Override
* protected void finalize() throws Throwable
* @return is using transaction connection {
*/ //hengsin: not the best way but it help to reduce connection and statement leakage.
public boolean isUseTransactionConnection() { if (p_stmt != null && !close)
return useTransactionConnection; {
this.close();
}
} }
} // CStatement } // CStatement