mysqli_fetch_assoc - что произойдет, если данные будут изменены в это время? - PullRequest
3 голосов
/ 14 августа 2011

В PHP я использую mysqli_fetch_assoc() в цикле while для получения каждой записи в определенном запросе.

Мне интересно, что произойдет, если данные изменились во время выполнения цикла (другим процессом или сервером), чтобы запись больше не соответствовала запросу. Это все еще будет доставлено?

Другими словами, фиксирован ли массив записей, которые вы выбираете, когда вы делаете query()? Или это не так?


Обновление:

Я понимаю, что это функция , что результирующий набор не изменяется при изменении данных, но что, если вы действительно этого хотите? В моем цикле меня не интересуют записи, которые уже обновлены другим сервером. Как я могу проверить это, не делая новый запрос для каждой записи, которую я получаю ??

UPDATE:

Подробное объяснение:

Я работаю над неким поисковиком-скребком, который ищет значения в базе данных. Это делается несколькими серверами одновременно. Предметы, которые были очищены, больше не нужно искать. Я не могу реально контролировать, какой сервер ищет какой элемент, я надеялся, что смогу проверить состояние элемента при получении набора записей. Поскольку это большой набор данных, я не передаю весь набор результатов перед поиском, я выбираю каждую запись, когда мне это нужно ...

1 Ответ

3 голосов
/ 14 августа 2011

Введение

Мне интересно, что произойдет, если данные будут изменены во время выполнения цикла (другим процессом или сервером), чтобы запись больше не соответствовала запросу. Это все еще будет доставлено?

Да.

Другими словами, исправлен ли массив извлекаемых записей, когда вы выполняете query ()? Или это не так?

Да.

СУБД не стоила бы своей соли, если бы она была уязвима для состязаний между обновлениями таблиц и итерацией набора результатов запросов.

Конечно, что касается самой базы данных, ваш запрос SELECT завершен, прежде чем какие-либо данные могут быть изменены; набор результатов кэшируется где-то в слоях между вашей базой данных и вашим PHP-скриптом.


Углубленный * * 1 021 В отношении Принцип КИСЛОТЫ *: В контексте баз данных одна логическая операция над данными называется транзакцией. Инициированные пользователем TRANSACTION могут охватывать несколько последовательных запросов, но 4.33.4 и 4.33.5 в ИСО / МЭК 9075-2 описывают, как это происходит неявно на уровне запроса: Следующие SQL-операторы инициируют транзакции Операторы SQL, т. Е. Если нет текущей транзакции SQL, и Выполняется SQL-оператор этого класса, затем SQL-транзакция инициируется, обычно до того, как выполнение этого SQL-оператора продолжается: Все SQL-schema заявления Следующие SQL-transaction операторы: <start transaction statement>. <savepoint statement>. <commit statement>. <rollback statement>. следующие SQL-data операторы: [..] <select statement: single row>. <direct select statement: multiple rows>. <dynamic single row select statement>. [..] [..] Кроме того, 4.35.6: Эффекты SQL-операторов в SQL-транзакции

Выполнение SQL-оператора внутри SQL-транзакции не имеет влияние на SQL-данные или схемы [..]. Вместе с сериализуемыми выполнение, это означает, что все операции чтения повторяются внутри SQL-транзакции на уровне изоляции SERIALIZABLE, кроме для:

1) Влияние изменений SQL-данных или схем и их содержимого явно сделанный самой SQL-транзакцией .

2) Влияние различий в значениях параметров SQL, предоставляемых извне процедур.

3) Эффекты ссылок на изменяющуюся во времени систему переменные, такие как CURRENT_DATE и CURRENT_USER.


Ваше более широкое требование

Я понимаю, что это особенность в том, что результирующий набор не изменяется при изменении данных, но что, если вы действительно этого хотите? В моем цикле меня не интересуют записи, которые уже обновлены другим сервером. Как проверить это, не делая новый запрос для каждой записи, которую я получаю ??

Вы не можете.

Хотя вы можете контролировать тип буферизации, выполняемой вашим соединителем (в данном случае MySQLi), вы не можете переопределить объясненный выше факт низкого уровня SQL: no INSERT или UPDATE или DELETE будет влиять на SELECT в процессе .

После завершения SELECT результаты являются независимыми; вы можете контролировать буферизацию передачи этих независимых данных, но это не поможет вам сделать то, что вам кажется.

Откровенно говоря, это довольно удачно, потому что то, что ты хочешь сделать, звучит довольно странно!


* Строго говоря, MySQL имеет только частичное ACID-соответствие для таблиц, отличных от таблиц с механизмами хранения не по умолчанию InnoDB, BDB и Cluster, и MyISAM не поддерживает [инициированные пользователем] транзакции .Тем не менее, кажется, что «я» должно оставаться применимым здесь;В противном случае MyISAM был бы бесполезен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...