Java JDBC挂在DELETE语句上

时间:2018-02-15 00:59:21

标签: java jdbc

我正在运行以下代码:

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(解释框架)

1 个答案:

答案 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-