Это работает так же, как и при отсутствии автоматической фиксации, но вы начинаете новую транзакцию, немедленно делаете INSERT, а затем немедленно COMMIT без задержки.
START TRANSACTION;
INSERT ...
COMMIT;
Это атом c, в том смысле, что никакой другой клиент не увидит вашу ВСТАВКУ в частично завершенном состоянии. Атомность не в скорости, а в том, чтобы убедиться, что изменение либо совершено полностью, либо нет вообще. В других сеансах нет полусоставленного состояния.
Кстати, синтаксис, который вы показываете, INSERT INTO ... VALUES ... WHERE NOT EXISTS ...
не имеет смысла. INSERT
не имеет предложения WHERE
. Возможно, вы думаете о INSERT
, который использует строки, выводимые оператором SELECT
:
INSERT INTO ...
SELECT ... FROM ... WHERE ...;
Если вы сделаете это, вы НЕ будете использовать предложение VALUES()
для вашего INSERT
.
Учитывая ваш обновленный вопрос, он не может работать так, как вы показываете.
SESSION1: вставить в foo ....., где не существует (выберите 1 в строке, где a = 1);
Если вы используете уровень изоляции транзакции по умолчанию REPEATABLE-READ, это приведет к блокировке пробела в bar
, где будет существовать строка, в которой будет a=1
. Это делается для того, чтобы гарантировать отсутствие изменений в последних зафиксированных записях в таблице, которую читал запрос.
SESSION2: вставить в bar (a) значения (1);
Это заставляет сеанс ждать, потому что он не может заблокировать разрыв для вставки. Время ожидания истечет с ошибкой, если сеанс 1 не будет зафиксирован в течение innodb_lock_wait_timeout
секунд (по умолчанию 50).