有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java JDBC挂起DELETE语句

我正在运行以下代码:

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 developer手动运行SQL语句“delete from test_table where is_valid=2”时,SQL语句“delete from test_table where is_valid=2”运行得很快,而INSERT和SELECT语句对JDBC代码和SQL developer手动运行都有效,只是delete语句在作为JDBC代码运行时挂起。我也尝试过PreparedStatements,但得到了与上面相同的结果(仅在从JDBC运行时删除语句)

JDBC executeQuery语句会因为DELETE语句而挂起(例如并发、锁定、权限等原因)有什么原因吗

我使用的是Oracle DB 11.2版、JDK 1.8.0_101和Tomcat v8。0, 司机:甲骨文。jdbc。驾驶员OracleDriver

并从Eclipse Java EE IDE for Web Developers版本:Neon运行服务器。3发布(4.6.3)

编辑1:

我已经更新了原始帖子中的代码(删除了自动提交行,还尝试将其设置为“true”,并将executeQuery()更改为executeUpdate(),但是,它仍然挂在executeUpdate()行上(这意味着执行无休止地尝试处理该行,但从未从中返回)

编辑2:

在JStack中,有许多被阻止的线程(尽管我通过关闭所有其他窗口等确保只有一个实例在运行):

线程34051:(状态=阻塞) -太阳。杂项。不安全的驻车(布尔,长)@bci=0(解释帧) -爪哇。util。同时发生的锁。锁支架。park(java.lang.Object)@bci=14,line=175(解释帧) -爪哇。util。同时发生的锁。AbstractQueuedSynchronizer$ConditionObject。wait()@bci=42,line=2039(解释帧) -爪哇。util。同时发生的LinkedBlockingQueue。take()@bci=29,line=442(解释帧) -组织。阿帕奇。公猫util。线程。任务队列。take()@bci=36,line=103(解释帧) -组织。阿帕奇。公猫util。线程。任务队列。take()@bci=1,line=31(解释帧) -爪哇。util。同时发生的线程池执行器。getTask()@bci=149,line=1067(解释帧) -爪哇。util。同时发生的线程池执行器。runWorker(java.util.concurrent.ThreadPoolExecutor$Worker)@bci=26,line=1127(解释帧) -爪哇。util。同时发生的ThreadPoolExecutor$Worker。run()@bci=5,line=617(解释帧) -组织。阿帕奇。公猫util。线程。TaskThread$wrappingranable。run()@bci=4,line=61(解释帧) -爪哇。朗。丝线。run()@bci=11,line=745(解释帧)

螺纹22275:(状态=阻塞) -爪哇。朗。丝线。sleep(long)@bci=0(编译帧;信息可能不精确) -组织。阿帕奇。卡塔琳娜。果心ContainerBase$ContainerBackgroundProcessor。run()@bci=46,line=1344(解释帧) -爪哇。朗。丝线。run()@bci=11,line=745(解释帧)

线程19715:(状态=阻塞) -爪哇。朗,反对。等待(长)@bci=0(解释帧) -太阳。杂项。GC$Daemon。run()@bci=51,line=117(解释帧)

线程16643:(状态=阻塞)

线程12547:(状态=阻塞) -爪哇。朗,反对。等待(长)@bci=0(解释帧) -爪哇。lang.ref.ReferenceQueue。删除(长)@bci=59,行=143(编译帧) -爪哇。lang.ref.ReferenceQueue。remove()@bci=2,line=164(编译帧) -爪哇。lang.ref.Finalizer$FinalizerThread。run()@bci=36,line=209(解释帧)


共 (1) 个答案

  1. # 1 楼答案

    您正在设置conn.setAutoCommit(false);,这意味着您需要在某个时刻提交事务

    试着设置conn.setAutoCommit(true);,看看有什么不同

    从oracle文档:

    http://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html

    When a connection is created, it is in auto-commit mode. This means that each individual SQL statement is treated as a transaction and is automatically committed right after it is executed. (To be more precise, the default is for a SQL statement to be committed when it is completed, not when it is executed. A statement is completed when all of its result sets and update counts have been retrieved. In almost all cases, however, a statement is completed, and therefore committed, right after it is executed.)

    此外,在这里使用executeUpdate代替executeQuery

    https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html#executeUpdate-java.lang.String-