【问题标题】:Why is our Connection Pool Closing?为什么我们的连接池关闭?
【发布时间】:2015-01-17 10:39:59
【问题描述】:

我们有一个在 Windows Server 2008 R2 上运行的 Apache Tomcat 7.0.54 上运行的 JSF2.0 网络服务器。我们在运行它的机器上有 2 个 SQL 服务器,另一个用于托管我们的库存软件。我们网页的一部分是验证添加的 PartNumber。在阅读了连接池是与 SQL 服务器通信的最佳实践之后,我们创建了一个并将其用于针对我们的库存软件进行的一些验证。

因为我想要一种能够检查连接池运行状况的方法,所以我创建了一个带有 ViewScoped 支持 bean 的测试页面,该 bean 验证了 2 个已知的良好部件号。今天是本周第二次出现“连接已关闭”的错误消息。由于我是连接池的新手,而且似乎找不到任何有关此的信息,我对我们没有正确设置的内容感到困惑。我刚刚重置了 Apache 服务器,它已备份并运行。所以.. 为了创建我们的连接池,我在应用的 META-INF/context.xml 中添加了一些代码。

    <Resource type="javax.sql.DataSource"
        name="jdbc/FOODB"
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
        driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
        url="jdbc:sqlserver://Foobar\Inventory;databaseName=FooInventory;user=johnDoe;password=astrongpassword;"
    />

我必须使用 ConnectionPool 的基本概念是我有一个名为 SqlAccessCommand 的接口。它或多或少是一种适配器模式。在我的测试页面中,我使用 RunUnsafe 方法,以便显示错误消息。所以这里是 RunUnsafe 方法。

protected static DataSource getDataSource() throws NamingException {
    Context context = (Context) new InitialContext().lookup("java:/comp/env");
    DataSource ds = (DataSource) context.lookup("jdbc/FOODB");
    return ds;
}
public static <T> T RunUnsafe(SqlAccessCommand<T> command) throws NamingException, SQLException {
    try {
        DataSource ds = getDataSource();
        try (Connection connection = ds.getConnection();
                PreparedStatement statement = connection.prepareStatement(command.getSqlStatement())) {
            command.prepareStatment(statement);
            try (ResultSet rs = statement.executeQuery()) {
                return command.getResults(rs);
            }
        }
    } catch (NamingException | SQLException e) {
        Logger.getLogger(AOSqlInformationHolder.class.getName()).log(Level.SEVERE, null, e);
        throw e;
    }
}

如您所见,我使用资源的尝试,无论如何都应该在使用后关闭我的连接。就像 try/catch/finally 一样,只是更清洁(IMO)。所以当我的连接打开时,这工作得很好。到目前为止 2x 现在我不得不重新启动服务器(因为我不知道如何以任何其他方式重新打开所述连接)我错过了什么?如果需要拼图的更多部分,请给我留言,我会发布我可以发布的内容。谢谢。

编辑

刚刚查看了日志文件,今天早上抛出了这个异常

com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset by peer: socket write error

根据迄今为止的 cmets,它被假定为超时。这个错误信息是否仍然指向那个方向?

【问题讨论】:

  • 连接可能在不活动后超时。
  • @ElliottFrisch 不是只有在我不关闭连接的情况下才这样吗?如果是这样,这不就是尝试资源的目的吗?
  • 使用池时连接不是close(d);他们回到游泳池。最终(如果连接未使用足够长的时间),数据库会假定连接不正确并关闭它。您需要查看解决方案的池配置选项。
  • @ElliottFrisch 查看编辑

标签: java sql-server jsf tomcat connection-pooling


【解决方案1】:

我建议使用放弃配置选项。

<Resource type="javax.sql.DataSource"
    name="jdbc/FOODB"
    factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
    driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
    url="jdbc:sqlserver://Foobar\Inventory;databaseName=FooInventory;user=johnDoe;password=astrongpassword;"
    removeAbandoned="true"
        removeAbandonedTimeout="60"
        logAbandoned="true" 
/>

【讨论】:

  • removeAbandoned应用程序 未正确关闭连接时很有用。但是,OP的问题是连接被数据库关闭。
【解决方案2】:

需要在连接池配置中添加一些选项1来检测连接是否仍然有效。

最简单的方法是运行一个简单的SQL语句 2来测试连接。

所以池配置可以是:

<Resource type="javax.sql.DataSource"
          name="jdbc/FOODB"
          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
          driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
          url="jdbc:sqlserver://Foobar\Inventory;databaseName=FooInventory;user=johnDoe;password=astrongpassword;"
          validationQuery="SELECT 1"
          validationQueryTimeout="1000"
          testOnBorrow="true"
/>

注意事项

  1. 查看可用选项:The Tomcat JDBC Connection Pool
  2. Efficient SQL test query or validation query that will work across all (or most) databases

【讨论】:

  • 感谢您找到此选项列表。我打算使用同一个文档中的废弃删除内容,但这似乎更合乎逻辑。
  • Mod up 因为这个答案实际上有一个解决方案。
  • 我认为应该注意的是,此解决方案会产生在每个查询上验证 Connection 的成本。 (可悲)没有灵丹妙药。
  • 使用此解决方案,仅执行语句以从池中获取连接。例如Connection conn = datasource.getConnection();。也许您想查看我的答案中提供的链接上的选项。
【解决方案3】:

您的连接几乎肯定会由于不活动而超时,根据您的日志消息 com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset by peer: socket write error 您可以阅读此@ 987654321@注意上面写着,

连接被对等方强行关闭。这通常是由于超时或重启导致远程套接字上的连接丢失造成的。

【讨论】:

    猜你喜欢
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多