我使用一段简单的代码来更新Oracle DB中的单行,查询只更新了一行,但执行仍然挂起在stmt.executeUpdate()上。
它不会抛出任何异常,但控件只会挂起。
我迷失在这里,因为同一段代码之前的工作正常。
try {
DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
conn = DriverManager.getConnection(url,username,pwd);
stmt = conn.createStatement();
String sql = "update report set status =" +"'"+NO+"'"+ " where name=" +"'"+ name+"'"+ " and user_id=" +"'"+sub+"'";
System.out.println(sql);
stmt.executeUpdate(sql)
答案 0 :(得分:12)
你永远不应该通过连接像这样的变量来创建语句。这使您可以SQL injection开放。此外,Oracle会将每个语句视为一个新语句,需要进行硬解析,这可能会导致性能问题。相反,请使用preparedStatement。
但是,我认为在你的情况下,这不是你问题的原因。当一个简单的更新挂起时,几乎总是这些原因之一:
我很确定你是第一种情况。出于一致性原因,Oracle会阻止多个用户同时更新同一行。这意味着如果修改的行被锁定,DML语句将等待另一个事务。它将一直等到阻塞事务提交或回滚。
我建议您在尝试通过之前执行SELECT ... FOR UPDATE NOWAIT
更新之前始终锁定一行。如果该行已被锁定,则会失败,您可以通过告诉用户此行当前被另一个会话锁定来正常退出。
您还必须确保没有交易以非公开状态结束。所有会话都应该在退出之前提交或回滚它们的更改(尽管不要使用自动提交)。
答案 1 :(得分:1)
使用JDBC PreparedStatement java docs
Class.forName("org.apache.derby.jdbc.ClientDriver");
Connection con = DriverManager.getConnection
("jdbc:derby://localhost:1527/testDb","name","pass");
PreparedStatement updateemp = con.prepareStatement
("insert into emp values(?,?,?)");
updateemp.setInt(1,23);
updateemp.setString(2,"Roshan");
updateemp.setString(3, "CEO");
updateemp.executeUpdate();
答案 2 :(得分:0)
我遇到了同样的问题,我对其他人一无所知,但是我通过关闭SQLplus来解决了!我认为这无法解决问题,因为在sqlplus在控制台上运行时某些查询可以工作,但是我关闭了它,现在每个查询都可以工作并且没有挂起!
如果遇到我们的问题,您可能想尝试一下!在控制台或您正在使用的任何其他数据库上退出Sqlplus,然后尝试再次运行代码!
答案 3 :(得分:-1)
改为使用PreparedStatement
http://www.mkyong.com/jdbc/jdbc-preparestatement-example-insert-a-record/
如果您声明,则每次服务器检查语法时都会消耗时间 所以去PreparedStatement