在java中管理数据库连接

在java中管理数据库连接,java,mysql,database,Java,Mysql,Database,一整天在谷歌上搜索这个问题让我比以往任何时候都更加困惑,所以我请求so的帮助。我试图使用mysql数据库的池连接,但我显然误解了一些东西。下面是一个应用程序的代码片段,该应用程序扫描文件夹以查找表示“作业”的新目录;找到后,将为找到的每个文件夹创建数据库对象。我将_insert()方法基于在SO上找到的模式。我的理解是,连接已正确关闭并返回到连接池。但是,我注意到,在添加8个对象之后,代码将挂起在getConnection()上。我发现默认的活动连接数是8,所以我添加了调试行,将活动连接数限制为

一整天在谷歌上搜索这个问题让我比以往任何时候都更加困惑,所以我请求so的帮助。我试图使用mysql数据库的池连接,但我显然误解了一些东西。下面是一个应用程序的代码片段,该应用程序扫描文件夹以查找表示“作业”的新目录;找到后,将为找到的每个文件夹创建数据库对象。我将_insert()方法基于在SO上找到的模式。我的理解是,连接已正确关闭并返回到连接池。但是,我注意到,在添加8个对象之后,代码将挂起在getConnection()上。我发现默认的活动连接数是8,所以我添加了调试行,将活动连接数限制为2。果然,在代码挂起之前只添加了两个对象

发生什么事了?我需要做哪些更改才能释放这些连接并将其添加回池中?我发现它提到了PoolableConnection类,但我对文档以及我发现的大多数其他示例似乎没有使用它的事实感到困惑

基于磁盘上特定目录中的文件夹在数据库中创建作业对象的Scanner类:

public class Scanner extends Thread {
    public void run() {     
        syncJobs();
    }

    void syncJobs(List<String> folderNames) {
        for (String folderName : folderNames) {
            Job job = addJobToDB(folderName);
        }
    }

    Job addJobToDB(String folderName ) {
        Job job = new Job();
        job.name = folderName;
        job.save();
        return job;
    }   
}
还有实际的作业对象(仅显示insert方法):

最后是提供连接的数据库对象:

import org.apache.commons.dbcp.BasicDataSource;
public final class Database {
    private static final BasicDataSource dataSource = new BasicDataSource();

    static {
        dataSource.setUrl("jdbc:mysql://localhost:3306/dbName?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC");
        dataSource.setUsername("user");
        dataSource.setPassword("****");     

        // This line added for debugging: sure enough, only 2 objects are created. 
        dataSource.setMaxActive(2);
    }

    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }      
}

尝试使用
closeNoisely(conn)
而不是
close静默(conn)
来检查连接是否确实正在关闭。我将所有三条语句从close静默(xxx)更改为close(xxx),它在close(conn)上抛出异常,抱怨连接已经关闭。我猜关闭结果集已经在处理连接了。注释掉该行,现在回到原始问题。关闭
ResultSet
不会关闭
连接。关闭
语句
将关闭其
结果集
,关闭
连接
将关闭其
语句
结果集
。方法
基本CDATA源。getConnection
是线程安全的吗?如果不将
synchronized
添加到方法
Database.getConnection
。将synchronized添加到getConnection,但没有效果。尝试使用
closenoisely(conn)
而不是
closequilly(conn)
来检查连接是否确实被关闭。我将所有三条语句从closequilly(xxx)更改为close(xxx)它在close(conn)上抛出了一个异常,抱怨连接已经关闭。我猜关闭结果集已经在处理连接了。注释掉该行,现在回到原始问题。关闭
ResultSet
不会关闭
连接。关闭
语句
将关闭其
结果集
,关闭
连接
将关闭其
语句
结果集
。方法
基本CDATA源。getConnection
是线程安全的吗?如果不将
synchronized
添加到方法
Database.getConnection
。将synchronized添加到getConnection,但没有效果。
public class Job extends DBObject {
    public int _insert()  {
        String query = "insert into jobs (name) values (?)";
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;    
        int id = 0;
        try {
            conn = Database.getConnection();
            ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
            ps.setInt(1, id);
            ps.executeUpdate();
            rs = ps.getGeneratedKeys();
            rs.next();
            id = rs.getInt(1);
        } catch (Exception e) {
            System.out.println(e.getMessage());             
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(ps);
            DbUtils.closeQuietly(conn);
        }
        return id;
    }       
}
import org.apache.commons.dbcp.BasicDataSource;
public final class Database {
    private static final BasicDataSource dataSource = new BasicDataSource();

    static {
        dataSource.setUrl("jdbc:mysql://localhost:3306/dbName?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC");
        dataSource.setUsername("user");
        dataSource.setPassword("****");     

        // This line added for debugging: sure enough, only 2 objects are created. 
        dataSource.setMaxActive(2);
    }

    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }      
}