Если вы не используете явные транзакции, каждый запрос обрабатывается как отдельная транзакция. Таким образом, запрос, который объединяет INSERT
и SELECT
, как ваш # 1, может зависеть от согласованности. Это примерно эквивалентно:
START TRANSACTION;
SET @max = (SELECT MAX(x) FROM bar);
INSERT INTO foo VALUES (@max);
COMMIT;
Однако транзакции не создают моментальный снимок всей базы данных во время ее запуска. InnoDB использует блокировку каждой записи. Так, в # 2 и # 3, если у вас есть сеанс A, обновляющий y
, в то время как сеанс B выполняет запрос, который вы показываете, записи, которые B обновляет, могут включать или не включать те, которые были изменены A, в зависимости от относительного порядка этих конкретных изменения. MyISAM, с другой стороны, использует блокировки на уровне таблицы, поэтому это не должно быть возможным; какой бы запрос не запустился первым, будет заблокирована таблица foo
, а другой запрос будет ждать его завершения, прежде чем начнет сканирование таблицы.