Транзакции: BEGIN, COMMIT, ROLLBACK
Объединяем несколько изменений в одну неделимую операцию.
Транзакция — это группа операций, которая выполняется по принципу «всё или ничего»: либо применяются все изменения, либо ни одного.
Зачем нужны транзакции
Классический пример — перевод денег: списать у одного, зачислить другому. Это две операции, но они должны выполниться вместе. Если после списания случится сбой, а зачисление не произойдёт, деньги «исчезнут». Транзакция гарантирует, что либо обе операции применятся, либо ни одна — это свойство атомарности, первая буква в ACID.
BEGIN ... COMMIT — применить всё
Транзакцию открывают командой BEGIN, а завершают COMMIT — в этот момент все изменения внутри становятся постоянными. Переведём 300 рублей от Ани Борису:
CREATE TABLE accounts (id INTEGER PRIMARY KEY, name TEXT, balance INTEGER);
INSERT INTO accounts (name, balance) VALUES ('Аня', 1000), ('Борис', 500);
BEGIN;
UPDATE accounts SET balance = balance - 300 WHERE name = 'Аня';
UPDATE accounts SET balance = balance + 300 WHERE name = 'Борис';
COMMIT;
SELECT name, balance FROM accounts;
Вывод:
Аня|700 Борис|800
Оба обновления применились как единое целое. После COMMIT изменения зафиксированы в файле базы.
ROLLBACK — отменить всё
Если внутри транзакции что-то пошло не так, выполняют ROLLBACK — и база возвращается в состояние до BEGIN, будто ничего не было. Изменим баланс, но откатим:
CREATE TABLE accounts (id INTEGER PRIMARY KEY, name TEXT, balance INTEGER);
INSERT INTO accounts (name, balance) VALUES ('Аня', 1000);
BEGIN;
UPDATE accounts SET balance = 0 WHERE name = 'Аня';
ROLLBACK;
SELECT name, balance FROM accounts;
Вывод:
Аня|1000
Несмотря на UPDATE ... SET balance = 0, после ROLLBACK баланс остался прежним — 1000. Изменение откатилось.
Транзакции и производительность
У транзакций есть приятный побочный эффект. По умолчанию каждая отдельная команда — это своя маленькая транзакция, и SQLite после каждой записывает данные на диск. Если нужно вставить тысячи строк, оберните их в одну транзакцию BEGIN ... COMMIT — диск тронется один раз, и вставка ускорится во много раз. Это стандартный приём массовой загрузки данных в SQLite.
Итог
- Транзакция — это «всё или ничего»:
BEGINоткрывает,COMMITфиксирует,ROLLBACKотменяет. - Атомарность защищает связанные операции (например, перевод денег) от частичного применения.
- Оборачивание массовых вставок в одну транзакцию резко ускоряет запись.