【问题标题】:Oracle JDBC DriverManager.getConnection() hangsOracle JDBC DriverManager.getConnection() 挂起
【发布时间】:2014-07-15 03:03:36
【问题描述】:

我们有几台服务器,每台服务器都运行一个 Oracle 数据库 11g 版本 11.2.0.1.0 - 64 位。我们像这样通过 JDBC 连接:

public Connection createConnection(String drvClass, String connURL, String user, String pass)
        throws ClassNotFoundException, SQLException {
    Class.forName(drvClass);
    Connection conn = DriverManager.getConnection(connURL, user, pass);
    for (SQLWarning warn = conn.getWarnings(); warn != null; warn = warn.getNextWarning()) {
        System.out.println("SQL Warning:");
        System.out.println("State  : " + warn.getSQLState());
        System.out.println("Message: " + warn.getMessage());
        System.out.println("Error  : " + warn.getErrorCode());
    }
    return conn;
}

drvClass 将是oracle.jdbc.OracleDriver。尝试连接的程序在每台服务器上运行。可以从具有完全相同连接属性的其他程序访问该数据库。

也可以让这个程序在另一台服务器上运行,并让它连接到有问题的数据库。它可以建立连接。 如果程序在本地服务器上运行,则该程序不起作用。我们尝试了 IP 和服务器名。

在一台服务器上,代码挂在DriverManager.getConnection() 我不知道为什么。有谁知道是什么原因造成的?

数据库日志中没有关于此的条目。

阻塞线程的堆栈跟踪:

"pool-27-thread-1" - Thread t@1483
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at oracle.net.ns.Packet.receive(Packet.java:239)
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:255)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:973)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:291)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:490)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:202)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:474)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at com.companyname.DBConnectionInternal.DBConnection.createConnection(DBConnection.java:19)
at com.companyname.exportadapter.ExportCollector.initDatabase(ExportCollector.java:259)
at com.companyname.exportadapter.ExportCollector.run(ExportCollector.java:120)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Locked ownable synchronizers:
- locked <50be77> (a java.util.concurrent.ThreadPoolExecutor$Worker)

如果我设置DriverManager.setLoginTimeout(10) 然后我得到 Io exception: Socket read timed out.

【问题讨论】:

  • 有多少客户端同时尝试访问数据库?也许您确实遇到了任何服务器限制(例如最大打开连接数)?
  • 数据库目前有大约 80 个连接。 SELECT value FROM v$parameter WHERE name = 'sessions' 返回 772 个可能的连接。
  • 阻塞线程的 Stacktrace 是什么? recv,sendv 可能会指出问题所在。
  • 我添加了阻塞线程的堆栈跟踪,但我找不到任何东西
  • 可以从不同的服务器运行这个应用程序。它可以毫无问题地连接到有问题的服务器。但是,一旦软件在此服务器上运行,连接就会挂起。

标签: java oracle jdbc oracle11gr2


【解决方案1】:

您可能会进行一些不必要的连接。

制作Connectionstatic ,每当您创建新连接时,请检查旧连接是否处于活动状态或关闭,然后您必须创建新连接,否则返回旧连接。

喜欢

 if(conn!=null & !conn.isClosed()){ 
// code for create connection
}

这也取决于数据库端的配置方式,因此请与系统的 DBA 进行检查。

我想建议使用连接池。

希望这会有所帮助。

【讨论】:

  • 我想我们还是不知道。也许客户端管理得很好,它关闭了它打开的每个连接。我宁愿认为问题可能在于许多客户端同时打开与数据库的连接并达到服务器限制 - 这可以通过在中间放置一些连接池来解决
  • 问题发生时,该用户没有打开的连接。连接在调用类的 finally 块中关闭(如果它已经打开)。
  • 创建静态连接是一个坏主意,它实际上会导致连接泄漏而不是阻止它们。我建议将 try-with-resources 与提供连接池的数据源结合使用。
【解决方案2】:

您可能希望为 ojdbc 驱动程序启用 JDBC 调试日志记录:http://docs.oracle.com/cd/B28359_01/java.111/b31224/diagnose.htm 这可能会给你一些关于司机在做什么的信息。

您是否尝试过从客户端机器远程登录到数据库服务器(以断言它是可访问的)?

【讨论】:

    【解决方案3】:

    服务器配置错误。由于某种原因,它配置了一个虚拟适配器,该适配器返回了一个无法连接的 ip。从外部解析工作正常。不知道为什么它从来没有因为错误的 IP 而超时。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-27
      • 2014-07-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-27
      • 1970-01-01
      • 2014-10-03
      相关资源
      最近更新 更多