【问题标题】:Multithreaded access to JDBC connection for only select case仅选择案例对 JDBC 连接的多线程访问
【发布时间】:2012-11-18 17:05:04
【问题描述】:

如果我将相同的连接分配给仅执行 select 语句(无 CRUD)的多个线程,这种情况线程安全吗?每个线程从同一个连接创建自己的preparedstatement 并执行它。 尽管每个线程都运行自己的结果集实例和准备好的语句对象,因此它看起来是线程安全的,但它们仍然使用与数据库的相同连接。我对 Oracle JDBC 驱动程序行为特别感兴趣。 先感谢您。

【问题讨论】:

    标签: java multithreading oracle jdbc prepared-statement


    【解决方案1】:

    Oracle 文档不禁止多线程访问。相反,他们通过声明“如果多个线程必须共享一个连接,请使用规范的开始使用/结束使用协议”来允许它。

    我认为这种谨慎可能是由于一个线程插入/更新和提交/回滚而另一个线程也插入/更新自己的数据并发出提交或回滚时的问题情况

    但是,在原始发布者的情况下,所有线程只发出 select 语句...仍然 resultset.next() 将前往数据库以使用相同的 tcp/ip 流检索行到数据库...这是哪里混乱开始了……

    “仅选择”情况下的行为未定义。

    【讨论】:

      【解决方案2】:

      我用谷歌搜索了一下,发现了这个:

      “Oracle® 数据库 JDBC 开发人员指南和参考” JDBC 和多线程

      “Oracle JDBC 驱动程序为使用 Java 多线程的应用程序提供全面支持并对其进行了高度优化。对连接的受控串行访问(例如连接缓存提供的访问)既是必要的,也是鼓励的。但是,Oracle 强烈不鼓励在多个线程之间共享数据库连接。避免允许多个线程同时访问一个连接。如果多个线程必须共享一个连接,请使用规范的开始使用/结束使用协议。”

      另外请记住,当您更新数据库时,您需要从更新连接中读取数据以使事务隔离正常工作。

      据我所知,从池中获取连接是一个相对便宜的过程。

      --编辑

      如果您担心与服务器的连接数,请查看“Oracle 连接管理器”

      “Oracle Connection Manager 通过充当连接集中器以跨单个网络连接“汇集”多个客户端数据库会话,使大量用户能够连接到单个服务器。”

      【讨论】:

        【解决方案3】:

        我相当确定 jdbc 规范要求连接是线程安全的(但不是语句/结果集),所以这将起作用。但是,某些 jdbc 驱动程序实现对于共享连接的效率较低,因此您绝对应该测试您是否获得了不错的性能。如果没有,您可能需要切换到多个连接。

        【讨论】:

        • 微软是肯定的。这让我们这里的其他开发人员之一感到紧张,但 MS 文档说这很好,我已经做了一段时间没有问题。 Oracle 的文档让我对此提出质疑,但听起来他们可能只是在谨慎行事。
        猜你喜欢
        • 1970-01-01
        • 2014-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-17
        • 2013-08-08
        • 2011-04-02
        相关资源
        最近更新 更多