I am getting Unable to acquire connection when there are active thread who has already done DB work and waiting for some other API calls.
This is flow and issue.
Request come and make DB select call. After getting data from DB, we make some API call to get some other data. If for some reason API call gets delay and at same time another thread come for flow then datasource timed out for getConnection for new request.
Original implementation is on Spring JPA, then I tried with JDBCTemplate and even old school code as getConnection, prepareStatement and then close one by one but every time same issue. If thread is busy then getconnection doesn't work.
In my webapp, I am using jdbc pool with 70 connection in production but in local using only 2 connection to reproduce issue. So it work fine with 2 request at same time, but if I make 3rd request while 2 are still in process, it throws error.
I am unable to understand, if I make connection close or release then why still datasource is not giving the connection.
Below is sample code by keeping all control by my hand.
try{
LOGGER.debug("Trying to get connection");
con = datasource.getConnection();
LOGGER.debug("Trying to prepareStatement");
ps = con.prepareStatement("select * from table where itemnumber=?");
ps.setString(1, itemnumber);
LOGGER.debug("Trying to executeQuery");
ResultSet rs = ps.executeQuery();
while(rs.next()) {
ufiles.add(rowMap.mapRow(rs, 0));
}
} catch (Exception e) {
LOGGER.error("Error in execution ",e);
} finally {
try {
if(ps!=null && !ps.isClosed()) {
ps.close();
}
if(con!=null && !con.isClosed()) {
con.close();
}
} catch (Exception e) {
LOGGER.error("Error in closing connection ",e);
}
}
Connection pool XML
<dataSource id="STREAMAPP" jndiName="jdbc/APPDB" type="javax.sql.ConnectionPoolDataSource">
<jdbcDriver libraryRef="ORACLEDRIVERLIB" />
<connectionManager connectionTimeout="10s" minPoolSize="1" maxPoolSize="2" maxIdleTime="30s" agedTimeout="7200s" />
</dataSource>
Application logs
Trying to get connection
Trying to prepareStatement
Trying to executeQuery
Converted java object gets return and then we make API calls in another class and methods. Meanwhile if another request come then after waiting for 10 seconds getConnections gets timeout.
Trying to get connection
Error in execution
java.sql.SQLTransientConnectionException: Connection not available, Timed out waiting for 10000
at com.ibm.ws.rsadapter.AdapterUtil.toSQLException(AdapterUtil.java:809)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:152)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:116)
ps
will skip closingcon
, leaking that connection. In any case, I'm not sure what you consider to be the problem. You say two requests are busy, so the third one fails after a timeout of 10 seconds: that is expected if you have a pool with size 2 (and the other 2 requests don't complete and return their connection to the pool before the timeout expires): all connections are in use, so there is no connection available for the third request. – Mark Rotteveel