Что такое ACID в контексте баз данных

«Что такое ACID в контексте баз данных» — вопрос из категории Базы данных, который задают на 32% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Свойство Описание Практический пример/Последствие нарушения
Aтомарность (Atomicity) Транзакция выполняется как единое целое: либо все ее операции выполняются, либо ни одна. Невозможно частичное выполнение. Банковский перевод: списание со счета A и зачисление на счет B должны произойти вместе. Без атомарности возможна ситуация, когда деньги списались, но не зачислились.
Cогласованность (Consistency) Транзакция переводит базу данных из одного валидного состояния в другое валидное состояние. Сохраняются все бизнес-правила, constraints (UNIQUE, FOREIGN KEY, CHECK). Правило: "Баланс счета не может быть отрицательным". Транзакция, приводящая к отрицательному балансу, должна быть отклонена, оставив БД в исходном согласованном состоянии.
Iзолированность (Isolation) Параллельно выполняющиеся транзакции не должны влиять друг на друга. Результат их совместного выполнения должен быть эквивалентен какому-то последовательному выполнению. Проблема "грязного" чтения (Dirty Read): Транзакция B видит незафиксированные изменения транзакции A. Если A откатится, B будет работать с несуществующими данными. Уровни изоляции (Read Committed, Repeatable Read, Serializable) управляют этой строгостью.
Dолговечность (Durability) После успешного завершения (commit) транзакции, внесенные ею изменения становятся постоянными и сохраняются даже в случае сбоя системы (отключение питания, крах сервера). Обеспечивается записью в WAL (Write-Ahead Log). Изменения сначала записываются в устойчивый журнал, и только затем применяются к основным файлам данных. После COMMIT и подтверждения клиенту, данные не будут потеряны.

Пример реализации в C# с TransactionScope:

using (var scope = new TransactionScope(
    TransactionScopeOption.Required,
    new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted },
    TransactionScopeAsyncFlowOption.Enabled))
{
    try
    {
        // 1. Операция в первой БД
        await dbContext1.Orders.AddAsync(newOrder);
        await dbContext1.SaveChangesAsync();

        // 2. Операция во второй БД или с внешним сервисом
        await inventoryService.ReserveItemAsync(newOrder.ItemId, newOrder.Quantity);

        // Если все операции успешны - фиксация (Durability)
        scope.Complete(); // Commit! Гарантируется Atomicity.
    }
    catch (Exception)
    {
        // При любом исключении TransactionScope автоматически выполнит Rollback.
        // Базы данных вернутся в состояние до начала транзакции (Consistency).
    }
} // Isolation контролируется выбранным уровнем.

Важно: Полная ACID-совместимость часто сопряжена с компромиссами в производительности и масштабируемости, особенно в распределенных системах. NoSQL БД часто жертвуют некоторыми свойствами ACID (например, полной изоляцией или немедленной согласованностью) в пользу доступности и partition tolerance (теорема CAP).

Видео-ответы