MySQL блокировка небуферизованного запроса не блокируется

Очевидно, согласно этому: 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 ответ

Решение

Блокировка, упомянутая в этом блоге, применяется только к механизму хранения MyISAM.

Если ваши таблицы определены для использования механизма хранения InnoDB (который является механизмом хранения по умолчанию начиная с MySQL 5.5), то применяется принцип, согласно которому читатели не блокируют средства записи.

Т.е. равнина SELECT ничего не блокирует в InnoDB.


Re ваш комментарий:

MyISAM имеет особый случай для INSERT, где вы можете вставить в таблицу, даже если она заблокирована другим сеансом, если вставка добавляется в конец данных.

https://dev.mysql.com/doc/refman/5.6/en/optimizing-queries-myisam.html говорит:

MyISAM поддерживает одновременные вставки: если в таблице нет свободных блоков в середине файла данных, вы можете ВСТАВИТЬ в нее новые строки одновременно с чтением других потоков из таблицы.

Другие вопросы по тегам