我正在运行以下代码:
protected String processDeleteQuery (String aTable) {
Statement stmt = null;
ResultSet rs = null;
Connection conn = this.conn;
String mResult = "Delete failed";
try {
stmt = conn.createStatement();
String sqlstr = "delete from test_table where is_valid=2";
stmt.executeUpdate(sqlstr);
mResult = "Delete successful";
} catch(SQLException sqlExcep) {
sqlExcep.printStackTrace();
mResult = "Delete failed - "+sqlExcep.getMessage();
} finally {
if(rs != null) { try { rs.close(); } catch(Exception e) {} }
if(stmt != null) { try { stmt.close(); } catch(Exception e) {} }
}
return mResult;
}
然而,代码挂在这一行:
stmt.executeUpdate(sqlstr);
永远不会从它回来,无休止地奔跑。 SQL语句"从test_table中删除,其中is_valid = 2"当我从SQL开发人员手动运行时,它运行得很快,INSERT和SELECT语句既适用于JDBC代码,也适用于SQL开发人员,只有DELETE语句作为JDBC代码运行时才会挂起。我也尝试过PreparedStatements,但是得到与上面相同的结果(从JDBC挂起时只有DELETE语句)。
JDBC executeQuery语句是否会因DELETE语句(例如并发,锁定,权限等原因)挂起而有什么原因?
我使用的是Oracle DB 11.2版,JDK 1.8.0_101和Tomcat v8.0, 使用驱动程序:oracle.jdbc.driver.OracleDriver
从Eclipse Java EE IDE for Web Developers运行服务器版本:Neon.3发布(4.6.3)
编辑1:
我已经更新了原帖中的代码(删除了自动提交行,也尝试将其设置为" true",并将executeQuery()更改为executeUpdate(),但是,仍然挂在executeUpdate()行(意味着执行无休止地尝试处理该行,但永远不会从它返回)
编辑2:
从JStack,有许多被阻塞的线程(尽管我通过关闭所有其他窗口确保只有一个实例正在运行,等等):
Thread 34051 :( state = BLOCKED) - sun.misc.Unsafe.park(boolean,long)@ bci = 0(解释框架) - java.util.concurrent.locks.LockSupport.park(java.lang.Object)@ bci = 14,line = 175(解释框架) - java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObject.await()@ bci = 42,line = 2039(解释框架) - java.util.concurrent.LinkedBlockingQueue.take()@ bci = 29,line = 442(解释框) - org.apache.tomcat.util.threads.TaskQueue.take()@ bci = 36,line = 103(解释框) - org.apache.tomcat.util.threads.TaskQueue.take()@ bci = 1,line = 31(解释框架) - java.util.concurrent.ThreadPoolExecutor.getTask()@ bci = 149,line = 1067(解释框架) - java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor $ Worker)@ bci = 26,line = 1127(解释框架) - java.util.concurrent.ThreadPoolExecutor $ Worker.run()@ bci = 5,line = 617(解释框架) - org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run()@ bci = 4,line = 61(解释框) - java.lang.Thread.run()@ bci = 11,line = 745(解释框架)
线程22275 :( state = BLOCKED) - java.lang.Thread.sleep(long)@ bci = 0(编译帧;信息可能不精确) - org.apache.catalina.core.ContainerBase $ ContainerBackgroundProcessor.run()@ bci = 46,line = 1344(解释框) - java.lang.Thread.run()@ bci = 11,line = 745(解释框架)
线程19715 :(状态=阻塞) - java.lang.Object.wait(long)@ bci = 0(解释框架) - sun.misc.GC $ Daemon.run()@ bci = 51,line = 117(解释框)
线程16643 :( state = BLOCKED)
线程12547 :( state = BLOCKED) - java.lang.Object.wait(long)@ bci = 0(解释框架) - java.lang.ref.ReferenceQueue.remove(long)@ bci = 59,line = 143(编译帧) - java.lang.ref.ReferenceQueue.remove()@ bci = 2,line = 164(编译帧) - java.lang.ref.Finalizer $ FinalizerThread.run()@ bci = 36,line = 209(解释框架)
答案 0 :(得分:1)
嗯,你正在设置conn.setAutoCommit(false);
,这意味着你需要在某个时候提交交易。
尝试设置conn.setAutoCommit(true);
,看看它有什么不同。
来自oracle docs:
http://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html
创建连接时,它处于自动提交模式。这意味着 将每个单独的SQL语句视为事务并且是 执行后立即自动提交。 (更多 精确,默认情况下是SQL语句提交时 完成,而不是在执行时。所有声明都完成了 已检索到其结果集和更新计数。几乎 但是,所有情况下,声明都已完成,因此已经提交, 它被执行后立即。)
此外,请在此处使用executeUpdate
代替executeQuery
:
https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html#executeUpdate-java.lang.String-