ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-10-08 14:05:38  阅读:269  来源: 互联网

标签:java jdbc tomcat connection-pooling


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

这是我用来创建DataSource的代码:

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秒在线程中执行一次调用时,我会偶尔得到一个异常“Statement is closed”.
我不确定为什么会这样.我认为它可能是驱动程序错误或与数据库连接失败的东西(在不同的服务器上运行).

我没有想法.我错过了什么?

我应该使用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尝试使用连接,但它已经关闭.

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

标签:java,jdbc,tomcat,connection-pooling
来源: https://codeday.me/bug/20191008/1872127.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有