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:
parent
5c448f6834
commit
5569168787
|
@ -570,7 +570,7 @@ public class DB_Oracle implements AdempiereDatabase
|
|||
cpds.setMaxPoolSize(15);
|
||||
cpds.setMaxIdleTimeExcessConnections(1200);
|
||||
cpds.setMaxIdleTime(900);
|
||||
m_maxbusyconnections = 12;
|
||||
m_maxbusyconnections = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -668,10 +668,12 @@ public class DB_Oracle implements AdempiereDatabase
|
|||
try
|
||||
{
|
||||
if (conn != null) {
|
||||
int numConnections = m_ds.getNumBusyConnections();
|
||||
if(numConnections >= m_maxbusyconnections )
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -505,13 +505,24 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
|||
getDataSource(connection);
|
||||
//
|
||||
Connection conn = m_ds.getConnection();
|
||||
ComboPooledDataSource cpds = (ComboPooledDataSource)m_ds;
|
||||
//System.out.println("Num Connections: " + cpds.getNumConnections() + ", Busy Connections: "
|
||||
// + cpds.getNumBusyConnections());
|
||||
// Connection conn = getDriverConnection(connection);
|
||||
//
|
||||
conn.setAutoCommit(autoCommit);
|
||||
conn.setTransactionIsolation(transactionIsolation);
|
||||
if (conn != null) {
|
||||
//
|
||||
conn.setAutoCommit(autoCommit);
|
||||
conn.setTransactionIsolation(transactionIsolation);
|
||||
|
||||
try
|
||||
{
|
||||
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;
|
||||
} // getCachedConnection
|
||||
|
||||
|
@ -551,7 +562,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
|||
cpds.setMaxPoolSize(15);
|
||||
cpds.setMaxIdleTimeExcessConnections(1200);
|
||||
cpds.setMaxIdleTime(900);
|
||||
m_maxbusyconnections = 12;
|
||||
m_maxbusyconnections = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -81,14 +81,14 @@ public class CCallableStatement extends CPreparedStatement implements CallableSt
|
|||
if (trx != null)
|
||||
{
|
||||
conn = trx.getConnection();
|
||||
useTransactionConnection = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p_vo.getResultSetConcurrency() == ResultSet.CONCUR_UPDATABLE)
|
||||
conn = DB.getConnectionRW ();
|
||||
m_conn = DB.getConnectionRW ();
|
||||
else
|
||||
conn = DB.getConnectionRO();
|
||||
m_conn = DB.getConnectionRO();
|
||||
conn = m_conn;
|
||||
}
|
||||
if (conn == null)
|
||||
throw new DBException("No Connection");
|
||||
|
|
|
@ -78,14 +78,14 @@ public class CPreparedStatement extends CStatement implements PreparedStatement
|
|||
if (trx != null)
|
||||
{
|
||||
conn = trx.getConnection();
|
||||
useTransactionConnection = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p_vo.getResultSetConcurrency() == ResultSet.CONCUR_UPDATABLE)
|
||||
conn = DB.getConnectionRW ();
|
||||
m_conn = DB.getConnectionRW ();
|
||||
else
|
||||
conn = DB.getConnectionRO();
|
||||
m_conn = DB.getConnectionRO();
|
||||
conn = m_conn;
|
||||
}
|
||||
if (conn == null)
|
||||
throw new DBException("No Connection");
|
||||
|
|
|
@ -38,7 +38,7 @@ import org.compiere.interfaces.*;
|
|||
*/
|
||||
public class CStatement implements Statement
|
||||
{
|
||||
protected boolean useTransactionConnection = false;
|
||||
protected Connection m_conn = null;
|
||||
|
||||
private boolean close = false;
|
||||
|
||||
|
@ -74,14 +74,14 @@ public class CStatement implements Statement
|
|||
if (trx != null)
|
||||
{
|
||||
conn = trx.getConnection();
|
||||
useTransactionConnection = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p_vo.getResultSetConcurrency() == ResultSet.CONCUR_UPDATABLE)
|
||||
conn = DB.getConnectionRW ();
|
||||
m_conn = DB.getConnectionRW ();
|
||||
else
|
||||
conn = DB.getConnectionRO();
|
||||
m_conn = DB.getConnectionRO();
|
||||
conn = m_conn;
|
||||
}
|
||||
if (conn == null)
|
||||
throw new DBException("No Connection");
|
||||
|
@ -739,17 +739,24 @@ public class CStatement implements Statement
|
|||
*/
|
||||
public void close () throws SQLException
|
||||
{
|
||||
if (p_stmt != null)
|
||||
{
|
||||
Connection conn = p_stmt.getConnection();
|
||||
p_stmt.close();
|
||||
|
||||
if (!close && !useTransactionConnection)
|
||||
{
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
close = true;
|
||||
try {
|
||||
if (p_stmt != null)
|
||||
{
|
||||
p_stmt.close();
|
||||
}
|
||||
} finally {
|
||||
if (m_conn != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_conn.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{}
|
||||
}
|
||||
m_conn = null;
|
||||
close = true;
|
||||
}
|
||||
} // 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;}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return is using transaction connection
|
||||
*/
|
||||
public boolean isUseTransactionConnection() {
|
||||
return useTransactionConnection;
|
||||
@Override
|
||||
protected void finalize() throws Throwable
|
||||
{
|
||||
//hengsin: not the best way but it help to reduce connection and statement leakage.
|
||||
if (p_stmt != null && !close)
|
||||
{
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
} // CStatement
|
||||
|
|
Loading…
Reference in New Issue