在我用Java编写并使用tomcat和sql server的Web应用程序中,无法通过键入connection.close()关闭数据库连接。当我将sp_who写入SSMS时,我可以看到在我的应用程序执行sql填充操作时,由我打开的睡眠连接计数增加了。
下面是一个示例代码:
BaseRepository baseRepository = new BaseRepository();
try{
baseRepository.createStatement();
baseRepository.stmt.executeUpdate("update AutoRunURLs set STATUS = 0");
}catch (SQLException e){
e.printStackTrace();
}finally {
baseRepository.cleanResources();
}
这是我上面使用的其他功能:
public void openConnection() {
try {
this.conn = ds.getConnection(); // ds is an instance of javax.sql.DataSource
this.isOpen = true;
} catch (Exception e) {
e.printStackTrace();
}
}
public void createStatement() {
try {
if (!this.isOpen) this.openConnection();
this.stmt = this.conn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
}
public void cleanResources() {
try {
if (this.rs != null) {
rs.close();
this.rs = null;
}
if (this.stmt != null) {
stmt.close();
this.stmt = null;
}
if (this.conn != null) {
this.closeConnection();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (this.conn != null) this.closeConnection();
}
}
public void closeConnection() {
try {
if (this.conn != null){
this.conn.close();
}
this.isOpen = false;
} catch (Exception e) {
e.printStackTrace();
}
}
当我运行以BaseRepository baseRepository ...
开头的第一部分时,会出现一个睡眠连接,通过键入sp_who可以看到它并没有关闭(我等待了一天)。这是为什么?我该如何预防?
我又遇到了一种情况。在我的tomcat配置中,我将“ maxIdle”值设置为10,但是即使一个星期后睡眠连接也增加到数千。为什么maxIdle不起作用?这是我的设置方式:
<Context>
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<Resource auth="Container" driverClassName="net.sourceforge.jtds.jdbc.Driver" maxTotal="999999" maxIdle="10" "Database info here..." validationQuery="select 1"/>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
如何解决这些问题?问候
编辑:我实际上是通过创建一个计划任务来管理它的,该任务每x分钟运行一次,并杀死超过y分钟的睡眠连接。但这不是我想要的方式。任何其他解决方案都很好。
答案 0 :(得分:1)
您正在使用Tomcat内置的连接池。这意味着它将保持连接打开以供重用。当您关闭代码中的连接时,它们实际上并没有关闭,而是返回到池中供您的应用程序重新使用。由于打开新连接需要时间,因此可以提高效率。
换句话说,没有什么错,并且保持打开状态的连接是预期的行为。
您可能希望将maxTotal
降低到更合理的值,例如10-20,而不是999999。
顺便说一句,您处理连接的方式有点奇怪,并且很容易泄漏连接。您可能只想在真正需要时从数据源获取连接,并了解try-with-resources,以便尽快关闭它。