【发布时间】: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);
}
}
我们尝试过的事情
我们能够从 oracle SQLDeveloper 会话对同一记录执行更新查询。
当应用程序卡住时,我们验证了相关表:
V$LOCKED_OBJECT、v$LOCK、v$session_longops、dba_blockers、v$session、dba_waitersjava应用程序无限等待。但我们找不到。如果我们重新启动应用程序,即使对于相同的记录更新或选择也会冻结。如果我们跳过该记录,则其他记录正在更新而没有任何问题。
造成这种情况的因素是什么?
堆栈跟踪
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