Все ленты — последние статьи

Транзакции в MySQL

Транзакции в MySQL

Очень часто изменения базы данных требуют выполнения нескольких запросов. Так, при покупке товара в электронном магазине требуется добавить запись в таблицу orders (заказы) и уменьшить число товарных позиций на складе (таблица products). В промышленных базах данных одно событие может затрагивать гораздо большее число таблиц и требовать выполнения многочисленных запросов.

 

Если при выполнении одного из запросов происходит сбой, это может нарушить целостность базы данных. Например, товар может быть продан, а число товарных позиций на складе не обновлено; деньги могут быть сняты с одного счета, но не перечислены на другой и т.п. Чтобы сохранить целостность базы данных, все изменения должны выполняться как единое целое — либо все изменения успешно выполняются, либо, в случае сбоя хотя бы одного из запросов, база данных принимает состояние, которое было до начала изменений.

Транзакция — это последовательность операторов SQL, выполняющихся как единая операция, которая не прерывается другими клиентами. То есть, пока происходит работа с записями таблицы (их обновление или удаление), никто другой не может получить доступ к этим записям.

Таблицы ISAM, MyISAM и HEAP не поддерживают транзакции. В настоящий момент их поддержка осуществляется только в таблицах BDB и InnoDB.

Транзакции позволяют объединять операторы в группу и гарантировать, что все операции внутри группы будут выполнены успешно. Если часть транзакции выполняется со сбоем, результаты выполнения всех операторов транзакции до места сбоя отменяются, приводя базу данных к виду, в котором она была до выполнения транзакции.

Следует обратить внимание, что транзакции имеют смысл только в случае с типами таблиц, которые их поддерживают: InnoDB и BDB. Если существующие таблицы имеют другой тип, например, MyISAM, для работы с транзакциями его следует изменить:
ALTER TABLE orders ENGINE = INNODB;
ALTER TABLE products ENGINE = INNODB;

Следует внимательно следить, чтобы при изменении типа MyISAM на любой другой в таблице отсутствовали FULLTEXT-индексы, т.к. никакой другой тип таблиц их не поддерживает.

По умолчанию MySQL работает в режиме автоматического завершения транцакций, т.е. как только выполняется оператор обновления данных, который модифицирует таблицу, MySQL тут же сохраняет изменения на диске. Для объединения в транзакцию нескольких операторов необходимо отключить этот режим. Это можно осуществить при помощи системной переменной AUTOCOMMIT:
SET AUTOCOMMIT=0;

После отключения режима автоматического завершения транзакций следует использовать оператор COMMIT, чтобы сохранить изменения на диске, либо оператор ROLLBACK, чтобы отменить изменения, выполненные с момента начала транзакции. Для того, чтобы включить обратно режим автоматического завершения транзакций, необходимо выполнить оператор
SET AUTOCOMMIT=1;

Для того, чтобы включить режим автоматического завершения транзакций только для отдельной последовательности операторов, можно воспользоваться оператором START TRANSACTION
START TRANSACTION;
SELECT @total := count FROM products WHERE id_prd = 17;
UPDATE products SET count = @total — 1 WHERE id_prd = 17;
COMMIT;

После выполнения оператора START TRANSACTION режим автоматического завершения транзакций остается включеным до явного завершения транзакции с помощью оператора COMMIT или отката транзакции посредством ROLLBACK.

Оператор START TRANSACTION появился в MySQL начиная с версии 4.0.11 и имеет два синонима: BEGIN и BEGIN WORK, появившихся еще в версии 3.23. Однако рекомендуется использовать именно START TRANSACTION.