mysql无缓冲查询锁定不锁定

时间:2014-03-07 18:04:44

标签: php mysql sql database unbuffered-queries

显然根据这个:http://www.tuxradar.com/practicalphp/9/4/9

  

在发出对mysql_unbuffered_query()的调用之间   你处理最后一行,表仍然被MySQL锁定   无法通过其他查询写入。如果你打算做冗长的话   处理每一行,这不好。

所以我试图模拟那个。请注意,使用MYSQLI_USE_RESULT与使用无缓冲查询同义。另请注意,表中现有大约60000个条目。

所以我有这段代码:

 $use_buffer = FALSE;
  $buffer = $use_buffer ? "SQL_BUFFER_RESULT" : "";

  $query = "SELECT $buffer * FROM table";
  $result = mysqli_query($db, $query, MYSQLI_USE_RESULT);
  $inserted = FALSE;
  $i = 0;
  $rand = rand();
  while($r = mysql_fetch_object($result)){
    if(!$inserted){
      mysqli_query($db, 'INSERT INTO table (something, somethingint) VALUES (\'NewValue' . $rand . '\', 1)');
      print('INSERTEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD');
      $inserted = TRUE;
    }
    if(!($i % 500)){
      $j = mysql_fetch_object(mysqli_query($db, "SELECT * FROM table WHERE something = 'NewValue$rand'"));
      print_r($j);
      print('still outputting');
      print_r($r);
    }
    $i++;
    if($i > 5000){
      break;
    }
  }
  mysql_free_result($result);

然后代码设法将新行插入到表中,而且即使表已被锁定,直到我完成了所有行的提取,该表仍然可以获取新表。

为什么会这样?我错过了什么?

1 个答案:

答案 0 :(得分:1)

该博客中提到的锁定仅适用于MyISAM存储引擎。

如果您的表被定义为使用InnoDB存储引擎(这是自MySQL 5.5以来的默认存储引擎),那么原则适用于读者不会阻止编写者

即。普通SELECT不会锁定InnoDB中的任何内容。


重新评论:

MyISAM有一个特殊的INSERT案例,只要插入附加到数据的末尾,即使它被另一个会话锁定,你也可以插入到表中。

https://dev.mysql.com/doc/refman/5.6/en/optimizing-queries-myisam.html说:

  

MyISAM支持并发插入:如果表在数据文件的中间没有空闲块,则可以在其他线程从表中读取的同时将新行插入其中。