【问题标题】:Is Postgres JDBC driver `org.postgresql.ds.PGSimpleDataSource` thread-safe?Postgres JDBC 驱动程序“org.postgresql.ds.PGSimpleDataSource”是线程安全的吗?
【发布时间】:2017-05-21 08:13:00
【问题描述】:

JDBC driver for Postgres 中,PGSimpleDataSource 是线程安全的吗?

也就是说,如果我使用该类的缓存单例实例,我可以将它传递给多个线程吗?每个线程可能同时调用getConnection。文档没有提到线程安全。

我试图避免(a)在Connection 上进行多线程调用和(b)使用连接池,如discussed in the doc。我希望每个 servlet 线程都有一个单独的 Connection

【问题讨论】:

  • @Gilberto 实际上,that doc you linked 只讨论 (a) 在 Connection 上执行查询,以及 (b) 使用连接池。我的问题是关于PGSimpleDataSource 上的getConnection,这是一个单独的主题。我问是因为我明显想避免(a)和(b)。
  • 我试图证明这一点:PostgreSQL™ JDBC 驱动程序是线程安全的。因此,如果您的应用程序使用多个线程,那么您不必担心复杂的算法来确保一次只有一个线程使用数据库。
  • @Gilberto 您的引用断章取义,回答我的问题。正如我上面所说,引用的文档解决了其他多线程问题,而不是我问的问题。

标签: java multithreading postgresql jdbc thread-safety


【解决方案1】:

我假设您不会在多个线程上更改数据源配置,因为那样它就不是线程安全的。你可以自己查看源代码,在https://github.com/pgjdbc/pgjdbcgetConnection的具体代码在BaseDataSource

public Connection getConnection(String user, String password) throws SQLException {
    try {
      Connection con = DriverManager.getConnection(getUrl(), user, password);
      if (LOGGER.isLoggable(Level.FINE)) {
        LOGGER.log(Level.FINE, "Created a {0} for {1} at {2}", new Object[]{getDescription(), user, getUrl()});
      }
      return con;
    } catch (SQLException e) {
      LOGGER.log(Level.SEVERE, "Failed to create a {0} for {1} at {2}: {3}",
          new Object[]{getDescription(), user, getUrl(), e});
      throw e;
    }
}

换句话说,它是DriverManager 的薄包装。 DriverManager 本身是线程安全的,那么org.postgresql.Driver 是否是线程安全的就成了一个问题。我没有时间尝试验证这一点,但可以说,如果这不是线程安全的(否则世界范围内的应用程序将因各种奇怪的竞争条件等而失败)。

附带说明:PGSimpleDataSource 不提供连接池,您可能需要考虑这是否适合您的用例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 2019-06-27
    相关资源
    最近更新 更多