java中的executeUpdate()需要很长时间才能执行

时间:2013-08-14 11:51:43

标签: java sql oracle jdbc

我使用一段简单的代码来更新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)

4 个答案:

答案 0 :(得分:12)

你永远不应该通过连接像这样的变量来创建语句。这使您可以SQL injection开放。此外,Oracle会将每个语句视为一个新语句,需要进行硬解析,这可能会导致性能问题。相反,请使用preparedStatement

但是,我认为在你的情况下,这不是你问题的原因。当一个简单的更新挂起时,几乎总是这些原因之一:

  1. 该行被另一笔交易锁定。
  2. 您正在将另一个表引用的密钥更新为unindexed foreign key
  3. 该表有一个ON UPDATE触发器,可以完成很多工作。
  4. 我很确定你是第一种情况。出于一致性原因,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