Trung Trịnh Trung Trịnh - 2 months ago 82
Java Question

JDBC Pool is suspended, , cannot allocate resources to applications

I deployed some apps in weblogic server. Few days ago, I traced logs and saw the error message:

2016-09-22 12:58:33,442 ERROR CommonService - ------- ERROR --------- java.sql.SQLException: Internal error: Cannot obtain XAConnection weblogic.common.resourcepool.ResourceDisabledException: Pool jdbc/*** is Suspended, cannot allocate resources to applications..
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResourceInternal(ResourcePoolImpl.java:377)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:342)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:329)
at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:417)
at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:324)
at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:94)
at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:63)
at weblogic.jdbc.jta.DataSource.getXAConnectionFromPool(DataSource.java:1677)
at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1475)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:446)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:403)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:364)
at [my-package].ConnectionHandler.newDatabaseConnection(ConnectionHandler.java:37)


I think that having a app leeks connections and doesn't return them to the pool

At temporary solution, I have to extended the the connection pool.
I try to research which apps made this problem and see that some strange codes below:

public class ConnectionHandler
{
..
public ConnectionHandler()
{
logger.trace("ConnectionHandler() constructor called");
}

static Connection newDatabaseConnection() throws SQLException
{
Connection conn;
try {
Context initContext = new InitialContext();
DataSource dataSource = (DataSource) initContext.lookup(LOOKUP_URL);
conn = dataSource.getConnection();
conn.setAutoCommit(false);
} catch (NamingException e) {
logger.error("------- ERROR ---------", e);
throw new ProcessingError("Could not obtain database connection!");
}
return conn;
}
}


This app (SOAP service) will using the code below to query data once having requests:

if (connectionHandler == null) {
connectionHandler = new ConnectionHandler();
}

try {
conn = connectionHandler.newDatabaseConnection();

// Some callable statements here

conn.commit();

logger.info("------- OK ---------");

} catch (SQLException e) {
logger.error("------- ERROR ---------", e);
} catch (InstantiationException e) {
logger.error("------- ERROR ---------", e);
} catch (IllegalAccessException e) {
logger.error("------- ERROR ---------", e);
} catch (DossierServiceException e) {
logger.error("------- ERROR ---------", e);
} finally {
jdbc.close(conn);
}


My confusions which I do not understand yet:


  1. Using the static connection in multi threads is ok?

  2. Create new class (ConnectionHandler) for each request and then get static connection?

  3. Just close the connection without closing the ResultSet, Callable statements?



Could you help me explanation for these ones or having some solutions else to prevent this problem?

Answer
  1. The method is static not the result it's returning. static method means that it's not necessary to have an instance of the enclosing class to call it

  2. Yes, that's a mistake, but, not such a big deal

  3. Yes, it would be better first to close the result set, statement and the connection, but this should do the job

The problem with this code is that there's no conn.rollback() in catch blocks and there may be uncaught runtime exceptions that will not be rolled back