当前位置: 首页 > 面试题库 >

Tomcat JDBC连接池问题:“语句已关闭”

龙德海
2023-03-14
问题内容

我有一个使用Tomcat JDBC连接池的服务器应用程序。

这是我用来创建数据源的代码:

PoolProperties connProperties = new PoolProperties();
connProperties.setUrl(resources.getProperty("db.url"));
connProperties.setDriverClassName(resources.getProperty("db.driver"));
connProperties.setUsername(resources.getProperty("db.user"));
connProperties.setPassword(resources.getProperty("db.password"));
connProperties.setJmxEnabled(true);
connProperties.setTestWhileIdle(false);
connProperties.setValidationQuery("SELECT 1");
connProperties.setTestOnReturn(false);
connProperties.setValidationInterval(30000);
connProperties.setTimeBetweenEvictionRunsMillis(30000);
connProperties.setMaxActive(500);
connProperties.setInitialSize(50);
connProperties.setMaxWait(10000);
connProperties.setRemoveAbandonedTimeout(60);
connProperties.setMinEvictableIdleTimeMillis(60000);
connProperties.setSuspectTimeout(60);
connProperties.setMaxIdle(50);
connProperties.setMinIdle(10);
connProperties.setLogAbandoned(false);
connProperties.setRemoveAbandoned(true);
connProperties.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
"org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");

dataSource = new DataSource();
dataSource.setPoolProperties(connProperties);

然后我有一种方法可以从池中获得连接

protected Connection getDbConnection() throws Exception
{
    dbConn = dataSource.getConnection();
    return dbConn;
}

每当我想执行一条语句时,我都会调用以下代码:

protected CallableStatement executeCSqlQuery(String sql) throws Exception
{
    CallableStatement cstmt;
    ResultSet rs = null;

    try {
        cstmt = getDbConnection().prepareCall(sql);     
        cstmt.execute();            
    } catch (SQLException e) {
        throw e;
    }

    return cstmt;
}

这是对先前代码的调用示例

try {
    cstmt = dbConnection.executeCSqlQuery(query);
    rs = cstmt.getResultSet();
} catch (Exception e) {
    // do smething
} finally {
    try {
        if (cstmt != null) {
            cstmt.close();
        }
        dbConnection.shutdown();
    } catch (Exception e) {
        // do something
    }
}

public void shutdown() {
    if (this.dbConn != null) 
        this.dbConn.close();
}

我面临的问题是,每隔X秒在线程中执行一次调用时,就会时不时地收到“语句已关闭”的异常。我不确定为什么会这样。我在想这可能是驱动程序错误或与数据库(在不同服务器上运行)的连接失败。

我没主意了。我想念什么?

我应该改用 c3p0 连接池吗?


问题答案:

我创建了赏金来帮助Reznik,但最终通过查看他的代码来弄清楚问题出在哪里。

问题是每次从池中获取新连接时,

protected Connection getDbConnection() throws Exception
{
    dbConn = dataSource.getConnection();
    return dbConn;
}

该对象dbConn将更新为新的连接。

例:

T1 调用 getDbConnection()

T2 调用 getDbConnection()

T1执行查询,处理resultSet和调用shutdown()

public void shutdown() {
    if (this.dbConn != null) 
        this.dbConn.close();
}

因为T2更新了对象,所以使用的连接T2将被关闭T1

T2 尝试使用连接,但该连接已关闭。

这样,不必总是更新连接,而只需返回它,然后添加额外的逻辑来关闭从池中获取的连接。



 类似资料:
  • 我有一个使用Tomcat JDBC连接池的服务器应用程序。 这是我用来创建数据源的代码:

  • 问题内容: 如果我在闲置了一段时间后启动应用程序,那么我曾经遇到以下错误。(我正在使用Spring + Hibernate + MySQL作为DB) 我通过将以下内容添加到我的servlet-context.xml中解决了这个问题。 我在这里问了这个问题,这个问题是解决方案所特有的。我需要知道为什么会遇到这个错误。 我尝试了上面链接中提供的第一个选项(使用autoReconnect = true配

  • 我向websphere V7添加了一个新的数据源。0,它工作正常,但在一段不活动时间后,池将返回死连接,java将进入等待状态,直到连接超时过期。如果我转到datasource管理页面并“测试连接”,连接池将再次工作。 我注意到,我们的oracle db会不时地关闭连接。 您知道如何从java重新激活连接吗?是否有其他方法来对抗Websphere池中的死连接?

  • 可能重复: dbcp中的已准备语句池 我正在构建一个Web应用程序,它使用Tomcat的数据库连池机制进行内部使用。我试图汇集准备好的语句,以便应用程序在检索数据时更有效。 据我所知,当连接、结果集和语句关闭时,连接将返回到池。如果设置了适当的标志,放弃的连接也会关闭并返回到池中。关闭连接意味着释放所有数据库游标和缓存的语句,包括准备好的语句。那么准备好的语句池有什么意义呢?

  • 所以基本上我有一个学校项目,它在while循环中包含一个switch语句。 假设我输入“1”,它运行案例“1”中的代码。然后它会在之后破裂。但默认代码也总是可以运行。 以下是案例“1”代码: 这是默认代码: 以下是输出: 我很有信心我的代码是正确的,但是如果我缺少什么,请告诉我如何修复它,谢谢。