gpt4 book ai didi

Java ConnectionPool 连接未关闭,卡在 'sleep'

转载 作者:搜寻专家 更新时间:2023-11-01 01:59:15 25 4
gpt4 key购买 nike

我有一个 Web 应用程序,它使用 JNDI 查找来连接到数据库。

连接工作正常并且返回查询没有问题。问题是连接没有正确关闭并停留在“ sleep ”模式(根据 mysql 管理员的说法)。这意味着它们在连接耗尽时变得不可用。

有人可以给我一些指示,告诉我如何才能使连接成功返回到池中。

public class DatabaseBean {

private static final Logger logger = Logger.getLogger(DatabaseBean.class);

private Connection conn;
private PreparedStatement prepStmt;

/**
* Zero argument constructor
* Setup generic databse connection in here to avoid redundancy
* The connection details are in /META-INF/context.xml
*/
public DatabaseBean() {
try {
InitialContext initContext = new InitialContext();
DataSource ds = (DataSource) initContext.lookup("java:/comp/env/jdbc/mysite");
conn = ds.getConnection();
}
catch (SQLException SQLEx) {
logger.fatal("There was a problem with the database connection.");
logger.fatal(SQLEx);
logger.fatal(SQLEx.getCause());
}
catch (NamingException nameEx) {
logger.fatal("There was a naming exception");
logger.fatal(nameEx);
logger.fatal(nameEx.getCause());
}
}

/**
* Execute a query. Do not use for statements (update delete insert etc).
*
* @return A ResultSet of the execute query. A set of size zero if no results were returned. It is never null.
* @see #executeUpdate() for running update, insert delete etc.
*/

public ResultSet executeQuery() {
ResultSet result = null;
try {
result = prepStmt.executeQuery();
logger.debug(prepStmt.toString());
}
catch (SQLException SQLEx) {
logger.fatal("There was an error running a query");
logger.fatal(SQLEx);
}
return result;
}

截图

public void close() {
try {
prepStmt.close();
prepStmt = null;

conn.close();
conn = null;
} catch (SQLException SQLEx) {
logger.warn("There was an error closing the database connection.");
}
}
}

这是在使用数据库连接的 javabean 中。

public LinkedList<ImportantNoticeBean> getImportantNotices() {

DatabaseBean noticesDBBean = new DatabaseBean();
LinkedList<ImportantNoticeBean> listOfNotices = new LinkedList<ImportantNoticeBean>();

try {
PreparedStatement preStmt = noticesDBBean.getConn().prepareStatement("SELECT pseudonym, message, date_to, date_from " +
"FROM importantnotices, users " +
"WHERE importantnotices.username = users.username " +
"AND NOW() >= date_from AND NOW() <= date_to;");

noticesDBBean.setPrepStmt(preStmt);
ResultSet result = noticesDBBean.executeQuery();

while (result.next()) {
ImportantNoticeBean noticeBean = new ImportantNoticeBean();

noticeBean.setAuthor(result.getString("pseudonym"));
noticeBean.setMessage(result.getString("message"));
noticeBean.setDateTo(result.getDate("date_to"));
noticeBean.setDateFrom(result.getDate("date_from"));

listOfNotices.add(noticeBean);
}

result.close();

} catch (SQLException SQLEx) {
logger.error("There was an error in ImportantNoticesBean.getImportantNotices()");
logger.error(SQLEx);
} finally {
noticesDBBean.close();
}
return listOfNotices;
}

<Context reloadable="true">

<Resource name="jdbc/mysite"
auth="Container"
type="javax.sql.DataSource"
username="user"
password="password"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mysite"
maxActive="10"
maxIdle="5"
maxWait="6000"
removeAbandoned="true"
logAbandoned="false"
removeAbandonedTimeout="20"
/>
</Context>

最佳答案

您似乎正确地关闭了连接 - 除了 prepStmt.close() 抛出 SQLException 的情况外,我找不到连接泄漏。

您使用的是什么池实现?当你关闭一个连接时,池不需要立即关闭底层的 MySQL 连接——毕竟​​那是连接池的意义所在!所以从 MySQL 的角度来看,连接看起来是活跃的,尽管你的应用程序没有使用任何连接;它们可能只是由 TC 连接池持有。

您可能想尝试连接池的设置。要求它在系统空闲时缩小连接池。或者,要求它定期刷新所有连接。或者,对它从 MySQL 等获得的并发连接数有一个严格的上限。

检查您的代码是否存在连接泄漏的一种方法是强制 ds.getConnection() 始终打开一个新的物理连接并使用 conn.close() 释放连接(如果您的连接池具有这些设置) .然后,如果您观察 MySQL 端的连接,您可能能够弄清楚代码是否真的存在连接泄漏。

关于Java ConnectionPool 连接未关闭,卡在 'sleep',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53128/

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