每个线程的新连接实例上的连接池 (JDBC)

Posted

技术标签:

【中文标题】每个线程的新连接实例上的连接池 (JDBC)【英文标题】:Connection Pooling over New Connection instance per Thread (JDBC) 【发布时间】:2010-08-22 09:36:27 【问题描述】:

我正在创建一个多线程应用程序。但是,当我有一个连接对象为所有线程提供服务时,我的应用程序经历了许多意外行为。

我进退两难了。我应该让每个线程创建、使用和处置自己的连接对象还是应该使用连接池?

我尝试过连接池,这会使应用程序痛苦地淋浴。但是,我的直觉是,如果我让每个线程都创建自己的连接对象,我可能会收到“连接过多”的错误。

如果有任何帮助,请告诉我。

问候。

【问题讨论】:

【参考方案1】:

无论线程问题如何,您都应该绝对选择连接池。它将大大提高连接性能。然后到线程问题,这确实是一个大问题。正常的 JDBC 习惯用法是获取关闭最短可能范围内的所有资源。 IE。一切都应该发生在同一个方法块中。您所描述的问题症状证实您没有正确关闭这些资源。

无论连接是否来自池,都应始终关闭。关闭非池连接将防止它在长时间保持打开状态时被数据库超时。关闭池连接实际上会将其释放回池中,并使其可用于下一次租约。

这是INSERT 的正常 JDBC 习惯用法的样子。

public void create(Entity entity) throws SQLException 
    // Declare.
    Connection connection = null;
    PreparedStatement statement = null;

    try  
        // Acquire.
        connection = database.getConnection();
        statement = connection.prepareStatement(SQL_CREATE);

        // Use.
        statement.setSomeObject(1, entity.getSomeProperty());
        // ...
        statement.executeUpdate();
     finally 
        // Close.
        if (statement != null) try  statement.close();  catch (SQLException logOrIgnore) 
        if (connection != null) try  connection.close();  catch (SQLException logOrIgnore) 
    

【讨论】:

您好 BalusC,感谢您的回复。我的线程现在正在处理它们自己的连接对象,关闭它们定义的 ResultSet 和 Statement 对象。这解决了“连接过多”的问题。 不客气。不要忘记将答案标记为已接受。另请参阅***.com/faq :) 我还通过引入锁定机制解决了线程问题。我在所有线程中引入了自定义启动、停止、暂停和恢复方法。三个线程只能在给定时间处于活动状态。 - 主要,“生产者”和“工人”。我有很多工人,但只有一个“生产者” 这是算法的伪代码 1. 启动主线程 2. 启动生产者线程 3. 启动 while-true 循环 4. 当生产者没有暂停时,主线程休眠 x 时间 5 . 启动一个工人,他将挑选与他/她有关的数据 :) 6. 当工人工作时,主线程休眠 x 时间 7. 结束 while-true 循环

以上是关于每个线程的新连接实例上的连接池 (JDBC)的主要内容,如果未能解决你的问题,请参考以下文章

JDBC连接池原理及分析

Tomcat JDBC连接池(Tomcat 9)

Flink JDBC Sink 和连接池

JDBC 连接池:连接重用?

JDBC 线程安全 数据库连接池

JDBC-连接池