Открыть сервис

Транзакция в SQL

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

История и развитие

Концепция транзакций возникла в 1970-х годах в связи с развитием реляционных баз данных и необходимостью обработки одновременных запросов. Ранние работы Джима Грея, Андреаса Рейтера и других исследователей заложили основы теории транзакций. В 1983 году Тео Хардер и Андреас Рейтер ввели аббревиатуру ACID (Atomicity, Consistency, Isolation, Durability), которая стала стандартом требований к транзакционным системам.

В языке SQL поддержка транзакций была стандартизирована в спецификации SQL-92 (ISO/IEC 9075). До этого разные СУБД (например, Oracle, IBM DB2, Microsoft SQL Server) реализовывали транзакции по-своему. Современные стандарты SQL (SQL:2016, SQL:2023) включают расширенные возможности управления транзакциями, такие как уровни изоляции, точки сохранения (savepoints) и распределённые транзакции.

Свойства ACID

Транзакция в SQL должна удовлетворять четырём свойствам, известным как ACID:

Жизненный цикл транзакции

Транзакция в SQL проходит через несколько состояний:

  1. Начало (BEGIN). Транзакция явно или неявно начинается. В большинстве СУБД первая команда DML (INSERT, UPDATE, DELETE) автоматически начинает транзакцию, если она не была начата явно. Для явного начала используется команда BEGIN TRANSACTION (или BEGIN / START TRANSACTION в разных диалектах).
  1. Активное выполнение. Внутри транзакции выполняются SQL-операторы. Все изменения временно фиксируются в памяти и в журнале транзакций, но не становятся окончательными до коммита.
  1. Фиксация (COMMIT). Команда COMMIT завершает транзакцию успешно. Все изменения, сделанные в рамках транзакции, становятся постоянными и видимыми для других транзакций.
  1. Откат (ROLLBACK). Команда ROLLBACK отменяет все изменения, сделанные с момента начала транзакции (или с последней точки сохранения). База данных возвращается в состояние, предшествовавшее началу транзакции.
  1. Точка сохранения (SAVEPOINT). Промежуточная метка внутри транзакции, к которой можно частично откатиться, не отменяя всю транзакцию. Это полезно для сложных операций, где часть изменений уже можно зафиксировать, а часть — отменить.

Уровни изолированности

Стандарт SQL определяет четыре уровня изолированности транзакций, которые решают проблему параллельного доступа:

На практике уровень изолированности по умолчанию различается в разных СУБД: PostgreSQL и Oracle используют READ COMMITTED, MySQL (InnoDB) — REPEATABLE READ, Microsoft SQL Server — READ COMMITTED.

Проблемы параллельного доступа

При одновременном выполнении нескольких транзакций могут возникать следующие аномалии:

Управление транзакциями в SQL

Явное управление

Большинство СУБД позволяют явно начинать, фиксировать и откатывать транзакции:

``sql BEGIN TRANSACTION; UPDATE accounts SET balance = balance - 100 WHERE account_id = 1; UPDATE accounts SET balance = balance + 100 WHERE account_id = 2; COMMIT; ``

Если в процессе выполнения возникает ошибка, транзакция откатывается:

``sql BEGIN TRANSACTION; UPDATE accounts SET balance = balance - 100 WHERE account_id = 1; -- Ошибка: недостаточно средств ROLLBACK; ``

Автоматические транзакции

В некоторых СУБД (например, MySQL с движком MyISAM, который не поддерживает транзакции) каждая отдельная SQL-команда выполняется как отдельная транзакция (автокоммит). В транзакционных движках (InnoDB, PostgreSQL) автокоммит может быть включён или выключен.

Точки сохранения

Точки сохранения позволяют частично откатить транзакцию:

``sql BEGIN TRANSACTION; INSERT INTO logs VALUES ('Start process'); SAVEPOINT after_insert; UPDATE data SET value = 100 WHERE id = 1; -- Если что-то пошло не так, откатываемся к точке сохранения ROLLBACK TO SAVEPOINT after_insert; COMMIT; ``

Транзакции в распределённых системах

В распределённых базах данных (например, в системах с репликацией или шардированием) транзакции могут затрагивать несколько узлов. Для обеспечения атомарности в таких сценариях используется протокол двухфазной фиксации (Two-Phase Commit, 2PC). Он включает фазу подготовки (когда все участники подтверждают готовность зафиксировать изменения) и фазу фиксации (когда координатор даёт команду на фиксацию). Однако 2PC может приводить к блокировкам при сбоях, поэтому в современных распределённых системах (например, в NewSQL-решениях) применяются более сложные протоколы, такие как Paxos или Raft.

Реализация в популярных СУБД

Практические рекомендации

Источники

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →