如果我将相同的连接分配给仅执行 select 语句(无 CRUD)的多个线程,这种情况下线程安全吗?每个线程从同一个连接创建自己的preparedstatement 并执行它。尽管每个线程都运行自己的结果集实例和准备好的语句对象,因此它看起来是线程安全的,但它们仍然使用与数据库的相同连接。我对 Oracle JDBC 驱动程序行为特别感兴趣。先感谢您。
3 回答
Oracle 文档不禁止多线程访问。相反,他们通过声明“如果多个线程必须共享一个连接,请使用有纪律的开始使用/结束使用协议”来允许它。
我认为这种谨慎可能是由于一个线程插入/更新和提交/回滚而另一个线程也插入/更新自己的数据并发出提交或回滚时出现问题的情况
但是,在原始发布者的情况下,所有线程只发出选择语句......仍然 resultset.next() 将前往数据库以使用相同的 tcp/ip 流检索行到数据库......这是混乱开始的地方...
对于“仅选择”情况,行为未定义。
我用谷歌搜索了一下,发现了这个:
“Oracle® 数据库 JDBC 开发人员指南和参考” JDBC 和多线程
“Oracle JDBC 驱动程序为使用 Java 多线程的应用程序提供全面支持并对其进行了高度优化。对连接的受控串行访问(例如由连接缓存提供的访问)既是必要的,也是值得鼓励的。但是,Oracle 强烈反对共享多个线程之间的数据库连接。避免允许多个线程同时访问一个连接。如果多个线程必须共享一个连接,请使用规范的开始使用/结束使用协议。
还要记住,当您更新数据库时,您需要从更新连接中读取数据以使事务隔离正常工作。
据我所知,从池中获取连接是一个相对便宜的过程。
- 编辑
如果您担心与服务器的连接数,请查看“Oracle 连接管理器”
“Oracle Connection Manager 通过充当连接集中器以跨单个网络连接“汇集”多个客户端数据库会话,使大量用户能够连接到单个服务器。”
我相当确定 jdbc 规范要求连接是线程安全的(但不是语句/结果集),所以这将起作用。但是,某些 jdbc 驱动程序实现对于共享连接的效率较低,因此您绝对应该测试您是否获得了不错的性能。如果没有,您可能需要切换到多个连接。