【问题标题】:Failed to update a row in oracle sql database from java jdbc, java code stuck at update无法从 java jdbc 更新 oracle sql 数据库中的一行,java 代码卡在更新
【发布时间】:2018-04-18 15:29:12
【问题描述】:

我遇到了一个问题,对于 Oracle SQL 表中的一个特定记录(随机),更新和选择无法从 Java JDBC 代码工作,Java 控件在该更新语句处无限期等待(应用程序卡住那里)。我在底部附上了堆栈跟踪。这个程序已经执行了几年,没有任何问题。

代码:

    public void updateRequestStatus(long req_id, int status){  
    int rowsAffected=0;
    Statement stmt = null;
    try{   
        stmt = objCon.createStatement();
        String strUpdQry="";
        '--- some java code
        '---
        strUpdQry= "UPDATE abcrequest SET status="+status+" where request_id="+req_id;
        this.logger.printString("Before executing Update Query :: with status: "+status+", Request id: "+req_id);

        rowsAffected=stmt.executeUpdate(strUpdQry);
        this.logger.printString("After executing Update Query:: "+status+", Request id: "+req_id);  
        this.objCon.commit();           
    }catch(SQLException sqle){
            this.lg.error("SQLException at :",sqle);
            this.logger.printString("SQLException occured  "+sqle.getMessage());
    }catch(Exception e){
            this.lg.error("Exception :",e);
            this.logger.printString("Exception occured in: "+e.getMessage());
    }       
    finally{
        closeStatement(stmt);
    }
}

我们尝试过的事情

  1. 我们能够从 oracle SQLDeveloper 会话对同一记录执行更新查询。

  2. 当应用程序卡住时,我们验证了相关表:V$LOCKED_OBJECTv$LOCKv$session_longopsdba_blockersv$sessiondba_waiters java应用程序无限等待。但我们找不到。

  3. 如果我们重新启动应用程序,即使对于相同的记录更新或选择也会冻结。如果我们跳过该记录,则其他记录正在更新而没有任何问题。

造成这种情况的因素是什么?

堆栈跟踪

   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at oracle.net.ns.Packet.receive(Unknown Source)
    at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
    at oracle.net.ns.NetInputStream.read(Unknown Source)
    at oracle.net.ns.NetInputStream.read(Unknown Source)
    at oracle.net.ns.NetInputStream.read(Unknown Source)
    at oracle.jdbc.ttc7.MAREngine.unmarshalUB1(MAREngine.java:931)
    at oracle.jdbc.ttc7.MAREngine.unmarshalSB1(MAREngine.java:893)
    at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:369)
    at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)
    at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteDescribe(TTC7Protocol.java:830)
    - locked <0x09c62c78> (a oracle.jdbc.ttc7.TTC7Protocol)
    at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2391)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2672)
    at oracle.jdbc.driver.OracleStatement.executeQuery(OracleStatement.java:572)
    - locked <0x04b068d8> (a oracle.jdbc.driver.OracleStatement)
    - locked <0x09c35338> (a oracle.jdbc.driver.OracleConnection)
    at xxxxx.DBActions.xxxxx.getRequestAttributes(Unknown Source)

Edit-1:添加了关于 ojdbc6 的新堆栈跟踪。

java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at oracle.net.ns.Packet.receive(Packet.java:282)
    at oracle.net.ns.DataPacket.receive(DataPacket.java:103)
    at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:230)
    at oracle.net.ns.NetInputStream.read(NetInputStream.java:175)
    at oracle.net.ns.NetInputStream.read(NetInputStream.java:100)
    at oracle.net.ns.NetInputStream.read(NetInputStream.java:85)
    at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:122)
    at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:78)
    at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1179)
    at oracle.jdbc.driver.T4CMAREngine.unmarshalSB1(T4CMAREngine.java:1155)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:279)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521)
    at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:194)
    at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1000)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
    at oracle.jdbc.driver.OracleStatement.executeUpdateInternal(OracleStatement.java:1814)
    at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:1779)
    - locked <0x09ec40f0> (a oracle.jdbc.driver.T4CConnection)
    at oracle.jdbc.driver.OracleStatementWrapper.executeUpdate(OracleStatementWrapper.java:277)
    at cas.com.database.MQDatabaseDts.updateProvRequestStatus(MQDatabaseDts.java:595)
    at cas.com.thread.NeoMQSenderThread.run(NeoMQSenderThread.java:188)
    at java.lang.Thread.run(Unknown Source)

【问题讨论】:

  • 这是您遇到的错误。还要在调用查询之前打印 strUpdQry 并将输出添加到问题中。
  • 您的应用程序是多线程的吗?是否同时有其他涉及该行的待处理事务?您是否尝试过更改事务隔离?
  • 最近有任何软件更新或补丁运行吗?数据库更新与 oracle java 驱动不同步?
  • OT,但您应该在 SQL 语句中使用绑定变量,而不是文字。
  • @DavideCavestro 感谢您的评论。该应用程序不是多线程的,并且从 java 代码中没有同时涉及该行的待处理事务,并且从 V$lock、V$LOCKED_OBJECT 表中验证了相同的情况,如果我跳过该记录,其他记录正在更新而没有任何问题,注意:这个问题是针对一些随机记录的。

标签: java sql oracle jdbc oracle-sqldeveloper


【解决方案1】:

您应该在执行此语句之前调用objCon.isValid(),因为此问题看起来您的连接已在幕后断开。如果连接无效,请获取一个新连接。

【讨论】:

  • 这似乎不是连接问题,因为即使我们处理相同的记录(有问题),代码也会冻结,如果我们跳过该记录并处理下一条记录,更新和选择工作正常。
  • 那么我建议您将驱动程序升级到更新的驱动程序。您在异常堆栈跟踪中有“TTC7Protocol”这一事实表明您正在使用超过 10 年的驱动程序。升级驱动程序很有可能会解决此问题。
  • 根据您的建议,我们已更新到 ojdbc6 并且问题仍在复制,我们有一个线索 a] 在 v$session 中,blocking_session 列中有一些带有 JDBC session_id 的 session_id,我们找不到任何锁。 b] 我已经更新了新的堆栈 wrt ojdbc6。请提出解决方案。
  • 您是否使用多个线程可以同时执行此 updateRequestStatus 方法并共享同一个连接?如果是这样,您可能需要重新审视您的逻辑,以确保您没有 2 个线程同时执行此方法,因为您可能最终陷入死锁。一种快速解决方法是同步方法。
  • 我们在整个过程中只使用一个线程,您能否解释一下堆栈的含义。 JDBC 是否在等待发送或接收...还有哪些其他可能的问题?
【解决方案2】:

上述问题是由于该 Oracle 版本中的并发问题,即 导致 java 会话被阻塞。

在实时更新到最新的 Oracle DB 版本后问题得到解决。

【讨论】:

    猜你喜欢
    • 2015-09-20
    • 1970-01-01
    • 2011-08-16
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多