Транзакция Mysql: фиксация и откат
Я обновил свой движок базы данных phpMyAdmin с MyISAM до INNODB, чтобы разрешить откат.
Это мой SQL-запрос:
START TRANSACTION;
UPDATE jkm_content SET state=0 WHERE title IN ('title-1','title2');
И результат:
start transaction;# MySQL returned an empty result set (i.e. zero
rows).
UPDATE jkm_content SET state=1 WHERE title IN ('title-1','title2');# 2 rows affected.
1) Таким образом, оператор сообщает мне, что затронуты 2 строки, но изменение нигде не отображается (ни в моей базе данных, ни на веб-сайте).Я подумал, что start transaction
позволит мне визуализировать изменения (во временной БД), а затем, если я удовлетворен, я "зафиксирую" запрос. (Я понимаю, что мне нужно commit
обновить базу данных, но если я commit
, изменение будет постоянным).
2) Тогда я не понимаю смысла rollback
, если я не могу увидеть эффект до его совершения. В чем будет разница между этими двумя запросами:
START TRANSACTION;
UPDATE jkm_content SET state=0 WHERE title IN ('title-1','title2');
И
START TRANSACTION;
UPDATE jkm_content SET state=0 WHERE title IN ('title-1','title2');
ROLLBACK;
3) если я правильно понял, все эти функции одинаковы:
START TRANSACTION
BEGIN
BEGIN WORK
2 answers
1) Все внесенные вами изменения видны в рамках одной транзакции. Если вы это сделаете
START TRANSACTION;
INSERT INTO MyTable VALUES ('Hi there');
SELECT * FROM MyTable;
Ваш вывод будет включать "Привет". Но если вы запустите второе подключение к базе данных, новая строка не будет отображаться до тех пор, пока вы не совершите транзакцию из первого подключения. Попробуйте поиграть с этим, используя два подключения к базе данных с помощью командной строки.
Вы не видите эффекта на своем веб-сайте, потому что у вас не может быть одной и той же транзакции в течение двух подключение к базе данных (новое подключение к базе данных будет установлено в начале вашего запроса).
2) Все транзакции, которые не были зафиксированы, будут откатаны при закрытии соединения с базой данных. Так что, если это ваши единственные два запроса, разницы нет. Однако есть разница между
START TRANSACTION;
INSERT INTO MyTable VALUES ('This one would be discarded on rollback');
ROLLBACK;
INSERT INTO MyTable VALUES ('This one will be permanent because not within transaction');
3) Да, это все одно и то же.
Изменения, внесенные вами в рамках одной транзакции, не видны другим транзакциям (за исключением транзакций с уровнем изоляции
READ UNCOMMITTED
) до тех пор, пока транзакция не будет зафиксирована.Существует огромная разница между откатом транзакции и сохранением ее открытой навсегда (или до тех пор, пока движок не отключит ее из-за тайм-аута). Последнее означает, что сервер не может освободить ресурсы, выделенные для поддержки транзакций. Кроме того, поскольку вы делаете
UPDATE
, mysql должен выдавать эксклюзивные блокировки для строк затронуты, и никакая другая транзакция не может обновить/удалить эти строки. Если у вас есть приложение, которое оставляет транзакции открытыми, вы, скорее всего, окажетесь либо со всеми подключениями, занятыми и ожидающими вечно, либо с кучей тупиков.Да, все они начинают новую транзакцию в mysql.