JDBC Oracle Thin ORA-02396 连接空闲超时

Posted

技术标签:

【中文标题】JDBC Oracle Thin ORA-02396 连接空闲超时【英文标题】:JDBC Oracle Thin ORA-02396 Connection idle timeout 【发布时间】:2014-04-15 19:47:38 【问题描述】:

我支持一些遗留代码,直到最近它一直运行良好。我正在寻找是否有 JDBC Oracle 瘦连接设置,我可以通过 Java 指定空闲超时(无连接池)?很多在线资源都提到了连接池......在我的情况下甚至可能(在非池情况下指定空闲超时)?还是空闲时间是特定数据库用户帐户的设置?

更新 + 问题

    我能够以用户身份登录,并运行查询以尝试找出资源限制。 select * from USER_RESOURCE_LIMITS; 然而一切都回来了“无限”。另一个值(比如来自 JDBC 连接)是否可以覆盖“UNLIMITED”?

    所以作业保持连接,而我们通过 DB 链接主动查询另一个系统大约 2 小时以上的良好持续时间......现在,为什么空闲超时甚至会发挥作用?

更新 #2

我们切换到不同的帐户(具有相同类型的数据库链接设置),并且能够像以前一样完成工作。哪一种指向 Oracle 用户配置文件的问题?但就像我说的,查询USER_RESOURCE_LIMITS 显示两个用户都有“无限”空闲时间。 DBA 也证实了这一点。还有什么可能导致这种差异?

更新 #3

堆栈跟踪等。

java.sql.SQLException: ORA-02396: exceeded maximum idle time, please connect again
ORA-06512: at line 1

    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:316)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:282)
    at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:639)
    at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:184)
    at oracle.jdbc.driver.T4CCallableStatement.execute_for_rows(T4CCallableStatement.java:873)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1086)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:2984)
    at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3076)
    at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4273)
    at com.grocery.stand.Helper.getAccess(Helper.java:216)
    at com.grocery.stand.fruitbasket.Dao.getPriceData(Dao.java:216)
    at com.grocery.stand.fruitbasket.Dao.getPricees(Dao.java:183)
    at com.grocery.stand.fruitbasket.UpdatePrice.updateAllFruitPrices(UpdatePrice.java:256)
    at com.grocery.stand.fruitbasket.UpdatePrice.main(UpdatePrice.java:58)
SQL Exception while getting Data from SYSTEM_B
Exception while updating pricing : ORA-01012: not logged on

Exception in thread "main" java.sql.SQLException: ORA-01012: not logged on

    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:316)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:277)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:272)
    at oracle.jdbc.driver.T4C7Ocommoncall.receive(T4C7Ocommoncall.java:129)
    at oracle.jdbc.driver.T4CConnection.do_rollback(T4CConnection.java:478)
    at oracle.jdbc.driver.PhysicalConnection.rollback(PhysicalConnection.java:1045)
    at com.grocery.stand.Helper.rollBack(Helper.java:75)
    at com.grocery.stand.fruitbasket.UpdatePrice.updatePartNumbers(UpdatePrice.java:291)
    at com.grocery.stand.fruitbasket.UpdatePrice.main(UpdatePrice.java:58)

连接代码

    public  static Connection openConnection() throws SQLException 


    String userName = propBundle.getString(DB_UID);
    String password = propBundle.getString(DB_PWD);
    String url = propBundle.getString(DB_URL);


    Connection conn = null;
    try 
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        conn = (Connection) DriverManager.getConnection(url, userName,
                password);
        conn.setAutoCommit(false);
     catch (SQLException sqle) 
        sqle.printStackTrace(System.out);
        throw sqle;
    
    return conn;

execute()行发生错误

public static void getSystemAccess(Connection dbConnection) throws SQLException 
  try 
      CallableStatement authStmt = null;
      String authorize = "CALL ABC.ACCESS_PROCEDURE@some_db_link()";
      authStmt = dbConnection.prepareCall(authorize);
      authStmt.execute();
      authStmt.close();
   catch (SQLException sqle1) 
      sqle1.printStackTrace();
      throw new SQLException(sqle1.getMessage());
  

【问题讨论】:

设置“DriverManager.setLoginTimeout()”怎么样? @sasankad 我假设LoginTimeout 与“空闲超时”不同? 【参考方案1】:

我不确定我是否理解您提出的问题。

您收到的错误表明您用于连接数据库的 Oracle 用户配置了一个配置文件(在 Oracle 中),该配置文件限制了连接可以空闲的时间量。当连接空闲时间过长时,Oracle 正在终止您的连接。通常,此类问题的解决方案是去找 DBA 并要求增加空闲时间,或者查看您的代码,看看为什么连接是打开的并且长时间未使用。如果您使用的是连接池(它看起来并非如此),那么某些连接长时间保持打开和空闲状态是有意义的。由于您似乎没有使用连接池,因此问题是应用程序长时间保持打开连接而不做任何事情是否有意义。如果应用程序在用户上午 9 点登录时打开连接,并且直到用户在下午 5 点关闭时才关闭连接,那么在数据库中为该用户调整 IDLE_TIME 设置可能是有意义的。否则,您可能需要调查应用程序长时间保持打开数据库连接而不做任何事情是否符合逻辑,或者是否可以修改应用程序以在不再需要时关闭连接。

【讨论】:

是的,我发现自己也在问同样的问题。为什么以及我们将连接保持打开这么长时间是否有意义(我个人不这么认为......但我有一些我不确定的东西 - 请参阅我的更新) 抱歉,我重新阅读了您的回复,发现我的评论并不完全合理。我在重复这个问题——连接保持开放这么长时间有意义吗? (我在想不)。不过这很奇怪;在那段时间里,我们保持连接打开,同时我们通过链接(可能每隔一分钟左右)主动查询另一个数据库......同样在这一点上,它似乎可以与一个用户一起工作,但在不更改代码的情况下不能与另一个用户一起工作.据说这两个用户帐户都拥有无限资源......这真的很奇怪。 @user1766760 - 错误来自哪个数据库?两个用户是否使用具有固定用户名和密码的相同数据库链接?还是每个用户都使用他们的个人凭据作为数据库链接的一部分? AFAIK,错误发生在我们即将对我们的数据库执行CallableStatement 以保持数据库链接打开时。所以我认为错误来自我们(我将在上面发布错误消息)。每个用户都有自己的登录名,但在后台访问相同的数据库链接。

以上是关于JDBC Oracle Thin ORA-02396 连接空闲超时的主要内容,如果未能解决你的问题,请参考以下文章

(转)jdbc:oracle:thin:@192.168.3.98:1521:orcl(详解)

jdbc连接oracle

找不到适合 jdbc:oracle:thin:@localhost:1521:xe 错误的驱动程序

显示错误 - 找不到适合 jdbc:oracle:thin:@localhost:1521:orcl 的驱动程序

使用jdbc连接上oracle的两种方法

Oracle 记录下jdbc thin client module名称