Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.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导致线程关闭_Java_C3p0 - Fatal编程技术网

Java C3P0导致线程关闭

Java C3P0导致线程关闭,java,c3p0,Java,C3p0,我有个奇怪的问题。我有一个实用程序类,它保存连接,并具有准备语句的函数。然后运行、关闭语句,一切正常 但是,当我尝试使用ComboPooledDataSource添加连接池时,我的线程关闭。我调试了它,我可以看到一些查询被成功执行,但是突然间一切都关闭了,只有c3p0线程仍然在运行。没有抛出异常 我尝试将池设置为单个连接,以尽可能地模拟工作代码,但也失败了。如果我将连接成员设置为池中的连接,一切正常,但是如果我尝试直接从池中使用,我会得到上面概述的行为 以下是一些示例代码: class DBUt

我有个奇怪的问题。我有一个实用程序类,它保存连接,并具有准备语句的函数。然后运行、关闭语句,一切正常

但是,当我尝试使用ComboPooledDataSource添加连接池时,我的线程关闭。我调试了它,我可以看到一些查询被成功执行,但是突然间一切都关闭了,只有c3p0线程仍然在运行。没有抛出异常

我尝试将池设置为单个连接,以尽可能地模拟工作代码,但也失败了。如果我将连接成员设置为池中的连接,一切正常,但是如果我尝试直接从池中使用,我会得到上面概述的行为

以下是一些示例代码:

class DBUtilityClass
{
   private java.sql.Connection connection;
   private ComboPooledDataSource connectionPool;

   public void DBUtilityClass()
   {
      connect();
   }

   private void connect()
   {
      connectionPool = new ComboPooledDataSource();
      connectionPool.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver   
      connectionPool.setJdbcUrl(urlString.toString());
      connectionPool.setUser(user);
      connectionPool.setPassword(password);
      connectionPool.setAutoCommitOnClose(true);

      connectionPool.setInitialPoolSize(1);
      connectionPool.setMinPoolSize(1);
      connectionPool.setAcquireIncrement(1);
      connectionPool.setMaxPoolSize(1);


   }

   //Version 1 - this works if I set the connection in the constructor 
   //or if I connect the connection manually without using the pool
   public Connection getConnection()
   {
      connection.setAutoCommit(true);
      return connection;
   }

   //Version 2 - This fails
   public Connection getConnection()
   {
      Connection temp = connectionPool.getConnection();
      temp.setAutoCommit(true);
      return temp;
   }

   public PreparedStatement getPreparedStatement(String sql)
   {
      Connection temp = getConnection();
      return temp.prepareStatement(sql);
   }
}

类中的函数
public PreparedStatement getPreparedStatement(String sql)
是一个
连接
泄漏。每次调用它时,都会从池中获取一个
连接
,但是引用会被删除,因此它永远不会
close()
并返回到池中

(很抱歉,在我们上面的评论帖子中,我花了这么长时间才看到这个!)

当存在一个共享的
连接时
,没有问题,一个连接保持签出状态。但是,当您使用池时,及时签出连接而不缓存连接时,您必须确保在完成后
close()

确保对
getConnection()
的每次调用都与对
close()
的调用相匹配。最简单的方法是

  • 这里不要使用getPreparedStatement(…)`函数,只需处理连接即可
  • 使用

  • 在构建了
    DBUtilityClass
    实例并获得了
    连接之后,您如何处理它?我有许多线程调用getPreparedStatement,执行该语句,然后关闭它。我正在运行一个单元测试,但它在安装过程中失败,甚至在它到达多线程部分之前。但是谁存储了
    DBUtilityClass
    的实例呢?(可能发布测试代码?)不,池是非常线程安全的。这就是重点。(我写了它。)我要加上这个作为答案,因为我在上面说了一句话,说这个班没问题,但我想让其他观众看到这个问题。
    try( Connection conn = myDBUtilityInstance.getConnection ) {
      try( PreparedStatement ps = conn.prepareStatement( sql ) ) {
        // do work here
      }
    }