Соответствует ли MongoDB принципам ACID?

«Соответствует ли MongoDB принципам ACID?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, но с оговорками. Поддержка ACID в MongoDB эволюционировала и теперь предоставляет гарантии, особенно с версии 4.0+.

Поддержка ACID в MongoDB:

Принцип Поддержка в MongoDB Комментарий
Atomicity (Атомарность) Полная На уровне документа: Все операции внутри одного документа атомарны.
Мультидокументные транзакции: Полная поддержка с версии 4.0 (реплика-сеты) и 4.2 (шардированные кластеры).
Consistency (Согласованность) Конфигурируемая Обеспечивается через валидацию схемы (JSON Schema), уникальные индексы и транзакции. В реплика-сете данные в конечном счёте согласованы (eventual consistency), но можно читать с readConcern: "majority" для гарантированной согласованности.
Isolation (Изоляция) Конфигурируемая По умолчанию: readCommitted для отдельных операций.
В транзакциях: snapshot isolation, что предотвращает «грязное» чтение, неповторяемое чтение и фантомы.
Durability (Долговечность) Конфигурируемая Гарантируется настройкой writeConcern. Например, { w: "majority", j: true } гарантирует запись на диск большинства реплик.

Пример мультидокументной транзакции:

const session = db.getMongo().startSession();
session.startTransaction({
    readConcern: { level: "snapshot" },
    writeConcern: { w: "majority" }
});
try {
    db.accounts.updateOne(
        { _id: 1 },
        { $inc: { balance: -100 } },
        { session }
    );
    db.accounts.updateOne(
        { _id: 2 },
        { $inc: { balance: 100 } },
        { session }
    );
    session.commitTransaction();
} catch (error) {
    session.abortTransaction();
    throw error;
}

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