当活动线程已经完成数据库工作并等待其他API调用时,我将无法获取连接。
这是流程和问题。
请求过来,使数据库选择呼叫。从数据库获取数据后,我们进行一些API调用以获取其他数据。如果由于某种原因API调用延迟并且同时又有另一个线程流,则对于新请求的getConnection数据源将超时。
最初的实现是在Spring JPA上,然后我尝试使用JDBCTemplate甚至是老式的代码作为getConnection,prepareStatement,然后每次都关闭一个问题,但每次都相同。如果线程繁忙,则getconnection无效。
在我的webapp中,我在生产中使用具有70个连接的jdbc池,但在本地仅使用2个连接来重现问题。因此,它可以同时处理2个请求,但是如果我在2个仍在处理中时发出第3个请求,则会引发错误。
我无法理解,如果我关闭或释放连接,那么为什么数据源仍然没有提供连接。
下面是通过手动控制所有示例代码。
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);
}
}
连接池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>
应用程序日志
试图建立连接试图准备声明尝试执行查询
已转换的Java对象得到返回,然后我们在另一个类和方法中进行API调用。同时,如果另一个请求到来,则在等待10秒钟后,getConnections将超时。
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)
经过更多研究后,所有指针均指向服务器上的GC和连接池实现。我没有在配置中找到任何解决方案,因此最后我将DAO调用和API调用分为两个入站请求。
消费者(UI)进行第1次调用以从DB中获取数据。然后,在成功响应UI之后,通过传递从1st(来自DB)接收的响应,调用另一个API来调用其余流程。
因此,作为线程完成后实际释放连接的池,因此在UI发出第一个请求之后,它立即使连接可用于下一个请求。
通过将其分成两部分,现在即使我可以使我的应用程序仅通过一个连接运行,并同时具有20-30个请求,因为我的数据库调用仅花费100毫秒,连接超时为10秒。因此,只需1个连接,我就可以处理大约90-100个请求。 :)