【问题标题】:Java multithreading and connection pooling with PreparedStatement使用 PreparedStatement 实现 Java 多线程和连接池
【发布时间】:2016-05-24 14:22:51
【问题描述】:

我目前有一个 Database 类,其中 PreparedStatement 成员变量在构造函数中初始化。像这样的:

public class Database
{
    private Connection connection;
    private PreparedStatement statement1, statement2, ...;

    public Database(String url, String user, String pass)
    {
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        connection = DriverManager.getConnection(url, user, pass);

        statement1 = connection.prepareStatement("sql stuff");
        statement2 = connection.prepareStatement("sql stuff");
        // etc
    }

    public User getUser(int userId)
    {
        // execute getUser statement
    }
    // and other similar methods
}

应用程序将是多线程的,我想使用 c3p0 进行连接池。但我不知道该怎么做。

假设我为每个线程创建了一个数据库对象,构造函数现在从池中获取一个连接。每个线程应该只调用其中一种方法(最多 5 个查询),然后结束。我每次都必须初始化所有准备好的语句吗?如果是的话,会不会太久?

有没有更好的方法可以做到这一点?

【问题讨论】:

  • 我不知道 c3p0 是否支持语句缓存,但有池支持。例如,Tomcat JDBC pool。使用这样的池,您可以重用准备语句的代码。如果已经缓存了类似的语句,则将返回缓存的副本,而不会产生实际准备语句的成本。
  • 我刚刚检查过,c3p0 确实有语句缓存。这是否意味着如果我在一个连接中准备语句,而另一个线程稍后从池中获得另一个连接,则语句将已经准备好?还是他们必须为池中的每个连接做好一次准备?

标签: java multithreading prepared-statement connection-pooling c3p0


【解决方案1】:

您需要使用提供池连接方式的数据源,然后您的应用程序从池中获取连接。

您可以在应用程序启动时创建in this example 等程序化数据源,也可以从网络服务器控制台配置(取决于网络服务器),然后通过 JNDI 在您的应用程序中获取数据源

Precompiled Statement 的预编译和 DB 端缓存导致整体执行速度更快,并且能够重用相同的 SQL 语句。

【讨论】:

  • 我认为问题在于反复产生准备声明的成本以及如何避免它。不是如何使用连接池。
  • 他问I would like to use c3p0 for connection pooling. But I have no idea how to go about it. 但我也会澄清第二部分
  • 是的,我知道如何使用数据源。问题是如何组织它,以便它可以被多个线程使用,并且不会花费太长时间的语句。
  • @dluga 太长取决于数据库返回数据的方式。
【解决方案2】:

连接池的一个优点是它可以重复使用现有的连接,这是您当前的实现所不具备的。那么问题是“每次初始化所有准备好的语句不会花费太长时间吗?”并不真正相关,因为每次创建一个新的数据库连接很可能比每次初始化准备好的语句花费更长的时间。即使准备好的语句每次都被初始化并且从不重复使用,我怀疑你会注意到任何性能差异,因为执行数据库语句比初始化准备好的语句需要更长的时间。

话虽如此,大多数 JDBC 驱动程序都可以选择缓存准备好的语句(即,这并不完全取决于连接池)。例如,参见 MySQL 配置选项 herecachePrepStmtsprepStmtCacheSizeprepStmtCacheSqlLimit)。但请记住,这些优化是“很高兴拥有”,首先要确保您的程序在多线程场景中正常工作(例如,确保您始终将从池中借用的连接返回到池中,即使在(运行时) 异常发生)并且是maintainable

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-07
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 2018-08-13
    相关资源
    最近更新 更多