Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.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 c3p0池在待机5-10分钟后断开连接_Java_Javafx_C3p0 - Fatal编程技术网

Java c3p0池在待机5-10分钟后断开连接

Java c3p0池在待机5-10分钟后断开连接,java,javafx,c3p0,Java,Javafx,C3p0,在我的Javafx应用程序中,我使用sftp连接到Hetzner.de上的远程服务器。为了管理连接,我使用带有以下参数的cp30库连接池: public Connection dbConnectSite() throws SQLException, PropertyVetoException { ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass("com.mysql.jdbc

在我的Javafx应用程序中,我使用sftp连接到Hetzner.de上的远程服务器。为了管理连接,我使用带有以下参数的cp30库连接池:

public Connection dbConnectSite() throws SQLException, PropertyVetoException {
    ComboPooledDataSource cpds = new ComboPooledDataSource();
    cpds.setDriverClass("com.mysql.jdbc.Driver");
    cpds.setJdbcUrl("jdbc:mysql://" + mySQLHost + ":" + mySQLPort + "/" + mySQLDBName + "?characterEncoding=UTF-8&autoReconnect=true"); // 192.168.100.100 v seti.
    cpds.setUser(mySQLUser);
    cpds.setPassword(mySQLPassword);
    cpds.setMinPoolSize(3);
    cpds.setMaxPoolSize(20); // Maximum number of Connections a pool will maintain at any given time.
    cpds.setAcquireIncrement(1);
    cpds.setTestConnectionOnCheckin(true); // If true, an operation will be performed asynchronously at every connection checkin to verify that the connection is valid.
    cpds.setTestConnectionOnCheckout(true); // If true, an operation will be performed at every connection checkout to verify that the connection is valid.
    cpds.setIdleConnectionTestPeriod(300); // If this is a number greater than 0, c3p0 will test all idle, pooled but unchecked-out connections, every this number of seconds.
    cpds.setMaxIdleTimeExcessConnections(240);
    cpds.setMaxIdleTime(3600); // Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire.
    cpds.setMaxStatements(100);
    cpds.setCheckoutTimeout(0); // The number of milliseconds a client calling getConnection() will wait for a Connection to be checked-in or acquired when the pool is exhausted. Zero means wait indefinitely.
    cpds.setMaxAdministrativeTaskTime(0); // Seconds before c3p0's thread pool will try to interrupt an apparently hung task. 
    cpds.setMaxConnectionAge(saytPort); // Seconds, effectively a time to live. A Connection older than maxConnectionAge will be destroyed and purged from the pool. Zero means no maximum absolute age is enforced. 
    cpds.setPreferredTestQuery("SELECT 1");
    dsSite = cpds;
    conSayt = dsSite.getConnection();
    return conSayt;
}
连接正常。连接的控制台日志为:

ноя 10, 2013 9:59:47 PM com.mchange.v2.log.MLog <clinit>
INFO: MLog clients using java 1.4+ standard logging.
ноя 10, 2013 9:59:47 PM com.mchange.v2.c3p0.C3P0Registry banner
INFO: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
ноя 10, 2013 9:59:47 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 1, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> z8kfsx8yiing6p1lp8nb2|3ba701c9, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kfsx8yiing6p1lp8nb2|3ba701c9, idleConnectionTestPeriod -> 300, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://sql249.your-server.de:3306/kombinezonik?characterEncoding=UTF-8&autoReconnect=true, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 22, maxIdleTime -> 3600, maxIdleTimeExcessConnections -> 240, maxPoolSize -> 20, maxStatements -> 100, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> SELECT 1, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> true, testConnectionOnCheckout -> true, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
nov 10, 2013 9:59:49 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> z8kfsx8yiing6p1lp8nb2|2bc60511, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kfsx8yiing6p1lp8nb2|2bc60511, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/kombadmin?characterEncoding=UTF-8&autoReconnect=true, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
当然,我会使用try with resources关闭语句和结果集:

try (Statement stmt = m.conSayt.createStatement(); ResultSet rs = stmt.executeQuery(SQL);) {
    // Contents.
} catch (SQLException ex){
    // Contents.
}

这里的问题是你使用c3p0的方式

每次获得连接时,您都要创建一个新的连接池,然后启动连接池,然后让它超出范围。请注意,在日志中,您正在三秒内初始化三个不同的c3p0池,每次尝试获取连接时初始化一次。不太好

你从不清理你的连接。(您实际上并没有清理这里提供的代码中的结果集和语句。)正如samlewis所说,看起来您只是想保持连接打开

所有这些都不是您应该如何使用连接池。如果要获取一个连接并保持其打开状态,只需使用DriverManager.getConnection(…)直接获取该连接,即可避免大量复杂性

除非您会发现,正如您已经发现的,长时间保持打开JDBC连接并期望重用它是运行应用程序的一种脆弱方式。这就是连接池要解决的问题

对于连接池,内容必须不同:

1) 您创建的ComboPooledDataSource?不要让它消失。在某个地方保留对它的引用,可能作为静态字段,也可能作为您使用的某个对象的成员。您应该为典型的应用程序部署创建one数据源one时间

2) 每次需要连接时,i)通过调用数据源上的getConnection()获取一个“新”连接;ii)做任何你需要做的工作;iii)使用后立即关闭()该连接

c3p0将维护一个连接池,因此所有这些都将是快速的。getConnection()不会建立到dbms的网络连接以建立新连接,它只会从池中为您提供一个连接。当您关闭()连接时,与dbms的连接实际上不会被破坏,只会被回收到池中。这是JDBC标准的透明连接池

[Oops!我没有注意到,提问者使用java 7 try with resources,应该是fina,只要资源之间有连接!]注意,调用函数在try{}块中创建结果集、语句或连接,根本不足以确保这些资源是关闭的()ed.您必须在最后一个区块中实际关闭它们:

Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try
{
    con = cpds.getConnection();
    stmt = cpds.createStatement();
    rs = stmt.executeQuery("SELECT something FROM somewhere");
    while ( rs.next() )
    {
       // do some stuff with results
    }
}
finally
{
   try { if (rs != null) rs.close() } catch (SQLException e) { e.printStackTrace(); }
   try { if (stmt != null) stmt.close() } catch (SQLException e) { e.printStackTrace(); }
   try { if (con != null) con.close() } catch (SQLException e) { e.printStackTrace(); }
}
同样,CPD不应该是局部变量。另一方面,在finally块中,您的连接应该(通常)在打开它的方法的范围内关闭

[请注意,finally块中的每个资源close()都封装在嵌套的try中,以确保一个close()中的异常不会阻止其他资源进行最佳尝试close()。您可以通过在helper方法中封装嵌套的try,使其更干净。]

其他一些评论:acquireIncrement为1通常是个坏主意,如果您已经在签出时测试连接,那么没有理由将TestConnectionOnOnCheckin设置为true。但就目前而言,这些都无关紧要,应用程序实际执行的唯一配置是jdbcUrl、用户和密码,因为您只获得一个连接,然后丢弃(嗯,尝试丢弃)池


值得解释的是,“试图放弃”。c3p0池生成它们自己的维护线程。当您构造和初始化新池,然后让它们在不关闭()的情况下离开作用域时,您正在创建线程和内存泄漏。无论何时处理完c3p0 ComboPooledDataSource,都必须调用close()[或更罕见的是调用静态方法DataSources.destroy(…])以关闭数据源。通常,当应用程序关闭或自行重置时,此操作只执行一次。

这里的问题是您使用c3p0的方式(恐怕是误用)

每次获得连接时,您都要创建一个新的连接池,然后启动连接池,然后让它超出范围。请注意,在日志中,您正在三秒内初始化三个不同的c3p0池,每次尝试获取连接时初始化一次。不太好

你从不清理你的连接。(您实际上并没有清理这里提供的代码中的结果集和语句。)正如samlewis所说,看起来您只是想保持连接打开

所有这些都不是您应该如何使用连接池。如果要获取一个连接并保持其打开状态,只需使用DriverManager.getConnection(…)直接获取该连接,即可避免大量复杂性

除非您会发现,正如您已经发现的,长时间保持打开JDBC连接并期望重用它是运行应用程序的一种脆弱方式。这就是连接池要解决的问题

对于连接池,内容必须不同:

1) 您创建的ComboPooledDataSource?不要让它消失。在某个地方保留对它的引用,可能作为静态字段,也可能作为您使用的某个对象的成员。您应该为典型的应用程序部署创建one数据源one时间

2) 每次需要连接时,i)通过调用数据源上的getConnection()获取一个“新”连接;ii)做任何你需要做的工作;iii)使用后立即关闭()该连接

c3p0将维护一个连接池,因此所有这些都将是快速的。getConnection()不会建立到dbms的网络连接以建立新连接,它只需将y
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try
{
    con = cpds.getConnection();
    stmt = cpds.createStatement();
    rs = stmt.executeQuery("SELECT something FROM somewhere");
    while ( rs.next() )
    {
       // do some stuff with results
    }
}
finally
{
   try { if (rs != null) rs.close() } catch (SQLException e) { e.printStackTrace(); }
   try { if (stmt != null) stmt.close() } catch (SQLException e) { e.printStackTrace(); }
   try { if (con != null) con.close() } catch (SQLException e) { e.printStackTrace(); }
}