1

显然根据这个: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);

但是随后代码设法将新行插入到表中,而且即使该表应该被锁定,直到我完成所有行的获取,也可以很好地获取该新表。

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

4

1 回答 1

2

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

如果您的表被定义为使用 InnoDB 存储引擎(这是自 MySQL 5.5 以来的默认存储引擎),那么该原则适用于reader 不阻塞 writer

即一个plainSELECT不会在InnoDB 中锁定任何东西。


回复您的评论:

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

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

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

于 2014-03-07T18:29:46.030 回答