使用java API选择行并在mysql中将它们更新为一个命令

时间:2014-12-15 10:53:36

标签: java mysql

我有这种情况,我需要从mysql中选择一批数据,然后相应地更新它们。

这就是我在伪代码方面做的事情:

//select
results --> select row1 from mytable where x=0;

//update
update --> update mytable  set x=1 where row1 in (results of previous query)

这是与之相关的代码:

Set<String>  output= select_row1(nextPatch);  // select_row1 returns a list of string where x=0
String blockQuery= "update mytable set x=1 where row1 in (" + ouput.toString + ");"  //output toString method is triggered to work accordingly.
update(blockQuery);  //this method will set column x=1 so it won't be used by other threads.

作为我的计划的一部分,我需要使用返回的output。所以必须有2个查询。

如果我只使用一台机器,这种机制很有效,但它在并发系统中失败了。 我想要做的是确保不再选择所选的行(通过设置x = 1),但是当运行的线程太多时。他们仍然可以选择相同的结果。

任何想法如何解决?

2 个答案:

答案 0 :(得分:2)

编辑

尝试锁定正在使用的表格(请在此处阅读Table-Locking Restrictions and Conditions)。警告这可能会导致线程抛出Exceptions,如果它们无法访问表,那么您可能需要在线程中捕获并处理它们。

LOCK TABLES mytable WRITE, mytable READ;
update mytable set x=1 where row1 in (select row1 from mytable where x=0);
UNLOCK TABLES;

你能不做这样的事吗?

update mytable set x=1 where row1 in (select row1 from mytable where x=0) 

答案 1 :(得分:0)

右, 首先感谢@MihaiC缩小搜索范围以找到解决方案。 我终于设法找到了这样做的方法。如果有人提出同样的问题,这是一个简短的说明。

所以问题是我想选择一组行,然后相应地为并发系统更新它们。

如果您只有一个线程,则使用两个单独的查询(如所示)将起作用。但是如果许多线程试图选择和更新,则会失败,因为他们会在第一个线程更新之前选择相同的行。

  1. "For UPDATE"
  2. 的末尾添加selectquery

    查询是:

    query = "SELECT row1 FROM mytable WHERE x=0 LIMIT 10;"
    

    *更改为:*

    query ="SELECT row1,x FROM mytable WHERE x=0 LIMIT 10 FOR UPDATE;"
    
    1. 请勿使用Statement,而是使用PreparedStatement
    2. <强> 是:

      Statement stmt = conn.createStatement();
      stmt.execute(selectQuery);
      ResultSet r= stmt.getResultSet();
      

      更改为:

      PreparedStatement stmt =conn.prepareStatement(query, ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE);
      stmt.execute(query);
      ResultSet r= stmt.getResultSet();
      
      1. 现在我们可以使用ReultsSet来更新行:
      2. <强> 是:

        while(r.next()){
           String row1=r.getString("row1");
        }
        

        更改为:

        while(r.next()){
           String row1=r.getString("row1");
           r.updateString("x", "1");
        }
        

        这将确保每个线程将选择一组行并相应地更新它们,而不会相互干扰。

        同样This post非常有用: