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 楼答案
您正在设置
conn.setAutoCommit(false);
,这意味着您需要在某个时刻提交事务试着设置
conn.setAutoCommit(true);
,看看有什么不同从oracle文档:
http://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html
此外,在这里使用
executeUpdate
代替executeQuery
:https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html#executeUpdate-java.lang.String-