Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我们的连接池要关闭?_Java_Sql Server_Jsf_Tomcat_Connection Pooling - Fatal编程技术网

Java 为什么我们的连接池要关闭?

Java 为什么我们的连接池要关闭?,java,sql-server,jsf,tomcat,connection-pooling,Java,Sql Server,Jsf,Tomcat,Connection Pooling,我们有一个JSF2.0 Web服务器,运行在ApacheTomcat7.0.54上,运行在WindowsServer2008R2上。我们有两台SQL Server在运行它的机器上,另一台托管我们的库存软件。我们网页的一部分是验证添加的零件号。在阅读了连接池是与SQL Server对话的最佳实践之后,我们创建了一个连接池,并将其用于针对清单软件的一些验证 因为我想要一种能够检查连接池运行状况的方法,所以我创建了一个测试页面,其中包含一个ViewScope支持bean,该bean验证了2个已知的良好

我们有一个JSF2.0 Web服务器,运行在ApacheTomcat7.0.54上,运行在WindowsServer2008R2上。我们有两台SQL Server在运行它的机器上,另一台托管我们的库存软件。我们网页的一部分是验证添加的零件号。在阅读了连接池是与SQL Server对话的最佳实践之后,我们创建了一个连接池,并将其用于针对清单软件的一些验证

因为我想要一种能够检查连接池运行状况的方法,所以我创建了一个测试页面,其中包含一个ViewScope支持bean,该bean验证了2个已知的良好部件号。今天是本周第二次出现错误消息“连接已关闭”。由于我是conenction pools的新手,似乎找不到任何有关这方面的信息,我对我们没有正确设置的内容感到困惑。我刚刚重置了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的接口。它或多或少是一种适配器模式。在我的测试页面中,我使用runsafe方法,以便显示错误消息。这里是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;
    }
}
受保护的静态数据源getDataSource()引发NamingException{
Context Context=(Context)new InitialContext().lookup(“java:/comp/env”);
DataSource ds=(DataSource)context.lookup(“jdbc/FOODB”);
返回ds;
}
公共静态运行不安全(SqlAccessCommand命令)引发NamingException,SQLException{
试一试{
DataSource ds=getDataSource();
try(Connection=ds.getConnection();
PreparedStatement=connection.prepareStatement(command.getSqlStatement()){
命令.准备声明(声明);
try(ResultSet rs=statement.executeQuery()){
return命令.getResults(rs);
}
}
}捕获(NamingException | SQLException e){
Logger.getLogger(AOSqlInformationHolder.class.getName()).log(Level.SEVERE,null,e);
投掷e;
}
}
正如您所看到的,我使用了try with resources,无论发生什么情况,它都应该在使用后关闭我的连接。就像try/catch/finally一样,只是更干净(IMO)。因此,当我的连接打开时,这一切正常。到目前为止,我必须重新启动服务器(因为我不知道如何以任何其他方式重新打开所述连接),我缺少什么?如果需要更多的谜题,请给我留言,我会尽我所能发布。多谢各位

编辑

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

com.microsoft.sqlserver.jdbc.SQLServerException:对等方重置连接:套接字写入错误


根据到目前为止的评论,它被假定为超时。此错误消息是否仍指向该方向?

根据com.microsoft.sqlserver.jdbc.SQLServerException:Connection reset by peer:socket write error的日志消息,您的连接几乎肯定会由于不活动而超时,您可以阅读以下说明:

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


您需要在连接池配置中添加一些选项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;"
        removeAbandoned="true"
            removeAbandonedTimeout="60"
            logAbandoned="true" 
    />
    
    
    
    连接可能在不活动后超时。@ElliottFrisch这不是只有在我不关闭连接的情况下才会发生吗?如果是这样的话,那不是try with resources的作用吗?当您使用池时,连接不会关闭;他们回到游泳池。最后(如果连接未使用的时间足够长),数据库会假定连接已损坏并将其关闭。您需要查看池配置选项以获得解决方案。@ElliottFrisch请参阅编辑谢谢您找到此选项列表。我打算使用同一文档中的废弃删除内容,但这似乎更符合逻辑。修改,因为这个答案实际上有一个解决方案。我认为应该注意的是,这个解决方案会导致在每个查询上验证
    连接的成本。遗憾的是,没有什么灵丹妙药。使用这种解决方案,执行语句只是为了从池中获得连接。e、 g.
    Connection conn=datasource.getConnection()。也许您想查看我的答案中提供的链接上的选项。
    removeAbandoned
    在应用程序未正确关闭连接时非常有用。但是,OP的问题是连接被数据库关闭。