【问题标题】:JdbcTemplate undertandingJdbc模板理解
【发布时间】:2013-04-16 21:30:55
【问题描述】:

这是我最近遇到的一些事情。

我对Spring的JdbcTemplate的理解是可以调用:

JdbcTemplate template = new JdbcTemplate(dataSource);
Connection conn = template.getDataSource().getConnection();

它使用传入的数据源返回来自 JdbcTemplate 的连接。如果我这样做:

template.getDataSource().getConnection().close();  

这是否只是获得另一个连接并关闭它,从而创建泄漏资源,还是获得它正在使用的连接?

编辑:

我在一个类中编写了 2 个方法,第一个是编写 JDBC 语句的老式低级方法(使用连接、语句和结果集):

public void execute(String tableName) {
    try {
        Class.forName("com.ibm.as400.access.AS400JDBCDriver");
        Connection con = DriverManager.getConnection("jdbc:as400://viper", "******", "******"); 
        Statement select = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);

        ResultSet rs = select.executeQuery ("SELECT * FROM ******." + tableName );
        logger.info("start clearing: " + tableName);

        while (rs.next ()) {
            rs.deleteRow();
        }
        logger.info("Step1 done clearing: " + tableName);

        ConnectionRecycler.recycleConnection(select, true, con);

        execute2(tableName);
    } catch (Exception eX) {
        logger.error(eX);
    }
}

另一种方法:

public void execute2(String tableName) {

    String nameOS = System.getProperty("os.name");
    String sql = (nameOS.equals("OS/400")) ? "DELETE from " + tableName : 
        "DELETE from " + tableName + " with none";

    JdbcTemplate templateSNPJ;

    templateSNPJ = new JdbcTemplate(this.snpjDataSource);
    templateSNPJ.update(sql);

    logger.info("Finished clearing: " + tableName);
    getServiceManager().unregisterService(this);
}

我以这种方式正确清理了资源。第二种方法,是使用:

JdbcTemplate.update(sqlCommand);

但似乎 JdbcTemplate 使连接保持活动的时间比为池配置的时间长。

我在 SO:Database connection management in Spring 上阅读了这篇文章,它避免了必须使用带有在 bean 中定义的 destroy-method=closed 参数的 dataSource 配置,如下所示:

    <bean id="SnpjDataSource" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean" destroy-method="close">
      <property name="uniqueResourceName" value="@#$$datasource"/>
      <property name="driverClassName" value="com.ibm.as400.access.AS400JDBCDriver"/>
      <property name="url" value="jdbc:as400://VIPER/******"/>
      <property name="user" value="FuManChu"/>
      <property name="password" value="*%$@^%$*#^$@^$@"/>
      <property name="maxPoolSize" value="10"/>
      <property name="reapTimeout" value="40"/>
    </bean> 

EDIT2:

ConnectionRecycler.recycleConnection 方法:

public static void recycleConnection(Statement state, boolean closeConnection, 
        Connection connect) {
    try {
        state.close();
        if (closeConnection) {
            connect.close();
        }
    } catch (SQLException sqlEx) {
        logger.error("Error closing resources!  ", sqlEx);
    }
}

【问题讨论】:

    标签: spring jdbc database-connection datasource connection-pooling


    【解决方案1】:

    这取决于您的数据源。如果您想确定使用相同的连接,请通过#getConnection 调用或使用SingleConnectionDataSource 对其进行处理。请注意,您必须在线程安全的环境中操作才能使用此数据源。它本身不是线程安全的。

    另外,您实际上不需要直接访问Connection。这就是JdbcTemplate 的全部意义所在。它隐藏了 JDBC 内部......避免了连接泄漏等风险。

    【讨论】:

    • 出于兴趣,您为什么需要访问连接?
    • @wmorricon365 我在顶部添加了更多信息。我在讨论第一次把它放在那里。据说 Spring 管理了后端资源的关闭,但似乎它没有清理资源。我的连接池的连接用完了。这个类是唯一在定时器线程中运行的东西。我还将其范围缩小到 JdbcTemplate 是泄漏。如果您查看我的 ConnectionRecycler.recycleConnection() 方法,它非常简单。
    • 嗨乔希。我注意到您正在使用AtomikosNonXADataSourceBean 并已汇集连接。我想知道你是否知道这个 DS 是如何提供连接并回收它们的。它的#close 是否实际上关闭了连接或将其重新添加到池中。在你看到失败之前你做了多少次迭代,它是否超过了com.atomikos.datasource.pool.ConnectionPool#borrowConnectionTimeout?即连接是否可以重用?此外,您是否尝试过在测试中使用替代数据源(将问题隔离到 JDBCTemplate、DS 或您的配置?
    • 其实我现在正在研究那个。该系统是从 IBM 的子公司 Genelco(用于人寿保险)购买的,并通过一些从 RPG 到 Java 的代码转换器运行。
    • 抱歉从我的办公桌上被拉开:这是编辑 - 实际上我现在正在研究那个。该系统是从 IBM 的子公司 Genelco(用于人寿保险)购买的,并通过一些从 RPG 到 Java 的代码转换器运行。要回答您的问题,迭代非常简单。如果我将池设置为 20 个连接(在上面的 xml 配置中)删除对 ConnectionRecycler 的调用,并将 reapTimeout 设置为 0,我可以在清空 connectionPool 之前准确地运行该服务 10 次。接下来的事情也许是测试一个替代数据源。
    猜你喜欢
    • 2012-12-15
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 2012-04-23
    • 1970-01-01
    相关资源
    最近更新 更多