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.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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue