gpt4 book ai didi

java - 池空。无法在 10 秒内获取连接

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:06:36 25 4
gpt4 key购买 nike

运行一段时间后,当我使用至少 20 个同时访问 servlet 的浏览器选项卡对我的 servlet 进行压力测试时,出现此错误:

java.sql.SQLException:[tomcat-http--10] 超时:池为空。无法在 10 秒内获取连接,无可用[size:200;忙碌:200;空闲:0; lastwait:10000].

这里是 XML 配置:

<Resource name="jdbc/MyAppHrd"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="200"
minIdle="10"
maxWait="10000"
initialSize="200"
removeAbandonedTimeout="120"
removeAbandoned="true"
logAbandoned="false"
minEvictableIdleTimeMillis="30000"
jmxEnabled="true"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
username="sa"
password="password"
driverClassName="net.sourceforge.jtds.jdbc.Driver"
url="jdbc:jtds:sqlserver://192.168.114.130/MyApp"/>

可能是什么问题?

更新:Java代码:

public class MyServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
private static final Log LOGGER = LogFactory.getLog(MyServlet.class);

private void doRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

CallableStatement stmt = null;
ResultSet rs = null;

Connection conn = null;
try {

conn = getConnection();

stmt = conn.prepareCall("{call sp_SomeSPP(?)}");
stmt.setLong(1, getId());

rs = stmt.executeQuery();

// set mime type
while (rs.next()) {
if (rs.getInt(1)==someValue()) {
doStuff();
break;
}
}
stmt = conn.prepareCall("{call sp_SomeSP(?)}");
stmt.setLong(1, getId());

rs = stmt.executeQuery();
if (rs.next()) {
// do stuff
}

RequestDispatcher rd = getServletContext().getRequestDispatcher("/SomeJSP.jsp");
rd.forward(request, response);
return;
} catch (NamingException e) {
LOGGER.error("Database connection lookup failed", e);
} catch (SQLException e) {
LOGGER.error("Query failed", e);
} catch (IllegalStateException e) {
LOGGER.error("View failed", e);
} finally {
try {
if (rs!=null && !rs.isClosed()) {
rs.close();
}
} catch (NullPointerException e) {
LOGGER.error("Result set closing failed", e);
} catch (SQLException e) {
LOGGER.error("Result set closing failed", e);
}
try {
if (stmt!=null) stmt.close();
} catch (NullPointerException e) {
LOGGER.error("Statement closing failed", e);
} catch (SQLException e) {
LOGGER.error("Statement closing failed", e);
}
try {
if (conn != null){
conn.close();
conn = null;
}
} catch (NullPointerException e) {
LOGGER.error("Database connection closing failed", e);
} catch (SQLException e) {
LOGGER.error("Database connection closing failed", e);
}
}

}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doRequest(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doRequest(request, response);
}

protected static Connection getConnection() throws NamingException, SQLException {
InitialContext cxt = new InitialContext();
String jndiName = "java:/comp/env/jdbc/MyDBHrd";
ConnectionPoolDataSource dataSource = (ConnectionPoolDataSource) cxt.lookup(jndiName);
PooledConnection pooledConnection = dataSource.getPooledConnection();
Connection conn = pooledConnection.getConnection();
return conn; // Obtain connection from pool
}

最佳答案

我建议您将 getConnection 方法更改为以下内容,您实际上可能会通过直接转到 javax.sql.PooledConnection 接口(interface)来删除池化支持

        InitialContext cxt = new InitialContext();
String jndiName = "java:/comp/env/jdbc/MyDBHrd";
DataSource dataSource = (DataSource) cxt.lookup(jndiName);
return dataSource.getConnection();

也可以使用类似 DBUtils#closeQuietly 的东西清理你的连接

更新:您正在从连接中删除池化支持。如果您运行以下命令并查看输出,您将看到直接从 DataSource 检索到的连接是一个包装了 PooledConnection 的 ProxyConnection。

public static void main(String[] args) throws Exception {

Properties properties = new Properties();
properties.put("username", "sa");
properties.put("password", "password");
properties.put("driverClassName", "net.sourceforge.jtds.jdbc.Driver");
properties.put("url", "jdbc:jtds:sqlserver://192.168.114.130/MyApp");

DataSourceFactory dsFactory = new DataSourceFactory();
DataSource ds = dsFactory.createDataSource(properties);
ConnectionPoolDataSource cpds = (ConnectionPoolDataSource) ds;
PooledConnection pooledConnection = cpds.getPooledConnection();

System.out.println("Pooled Connection - [" + ds.getConnection() + "]"); // Close will return to the Pool
System.out.println("Internal Connection - [" + pooledConnection.getConnection() + "]"); // Close will just close the connection and not return to pool

}

关于java - 池空。无法在 10 秒内获取连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13976305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com