> Есть ли транзакции в MongoDB (Node.js, MongoDB, C# /.NET, JavaScript, Go)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: TrendTech

Стек: Node.js, MongoDB, C# /.NET, JavaScript, Go

> Пример ответа

Короткий ответ

Да, в MongoDB есть транзакции, но с ограничениями. Начиная с версии 4.0 поддерживаются multi-document ACID транзакции в реплика-сетах, а с 4.2 - и в шардированных кластерах. Однако транзакции в MongoDB имеют более высокий latency и overhead по сравнению с одиночными операциями, поэтому их следует использовать только когда действительно нужна атомарность нескольких документов.

Подробное объяснение

MongoDB поддерживает два уровня транзакций:

  1. Одиночные операции - атомарны на уровне одного документа. Это базовый механизм, работающий всегда.

  2. Multi-document транзакции - ACID-транзакции, работающие с несколькими документами в одной или разных коллекциях. Они появились в MongoDB 4.0 и требуют:

    • Реплика-сет (replica set) - для версий 4.0-4.2
    • Шардированный кластер - с версии 4.2

Ограничения транзакций:

  • Максимальная длительность - 60 секунд (по умолчанию, настраивается)
  • Максимальный размер oplog - влияет на количество одновременных транзакций
  • Не поддерживаются в standalone инсталляциях
  • Snapshot isolation - транзакции видят консистентный срез данных на момент начала
  • Write conflicts - при конфликте транзакция откатывается, требуется retry

Внутренняя реализация использует WiredTiger storage engine с механизмом snapshot isolation. Транзакции записываются в oplog и применяются атомарно.

На практике

В реальных проектах транзакции MongoDB стоит применять осторожно:

  • Когда использовать: финансовые операции, заказы с обновлением нескольких сущностей, инвентаризация - где атомарность критична
  • Когда избегать: high-throughput системы, real-time аналитика, bulk-операции - overhead транзакций может снизить производительность в 2-5 раз
  • Альтернативы: вложенные документы (embedded documents) часто решают ту же задачу без транзакций; денормализация данных; eventual consistency с компенсирующими операциями

На Node.js и Go транзакции реализуются через session API. В C#/.NET - через MongoClient.StartTransaction().

Пример кода

JAVASCRIPT
// Node.js с MongoDB driver
const session = client.startSession();
try {
await session.withTransaction(async () => {
const accounts = client.db('bank').collection('accounts');
const orders = client.db('shop').collection('orders');
// Атомарно: списать с одного счета и создать заказ
await accounts.updateOne(
{ userId: 'user1', balance: { $gte: 100 } },
{ $inc: { balance: -100 } },
{ session }
);
await orders.insertOne(
{ userId: 'user1', item: 'laptop', price: 100 },
{ session }
);
});
} finally {
await session.endSession();
}
GO
// Go с mongo-go-driver
session, err := client.StartSession()
if err != nil {
log.Fatal(err)
}
defer session.EndSession(context.Background())
err = mongo.WithSession(context.Background(), session, func(sc mongo.SessionContext) error {
_, err := accounts.UpdateOne(sc,
bson.M{"userId": "user1", "balance": bson.M{"$gte": 100}},
bson.M{"$inc": bson.M{"balance": -100}})
if err != nil {
return err
}
_, err = orders.InsertOne(sc,
bson.M{"userId": "user1", "item": "laptop", "price": 100})
return err
})

Как отвечать на собеседовании

Начни с чёткого "да, есть", затем уточни версию и условия (replica set). Подчеркни trade-off: транзакции есть, но они не бесплатны. Приведи пример из практики, когда ты использовал транзакции или осознанно отказался от них в пользу денормализации. Покажи понимание внутреннего устройства (WiredTiger, snapshot isolation). Если спросят про шардирование - добавь, что с 4.2 транзакции работают и в шардированных кластерах, но с дополнительными ограничениями.

Что проверяет интервьюер

  • Знание эволюции MongoDB (версии 4.0, 4.2)
  • Понимание ACID в контексте NoSQL
  • Умение выбирать между транзакциями и денормализацией
  • Практический опыт с session API и обработкой ошибок (write conflicts, retries)
  • Осознание performance trade-offs

Типичные ошибки

  • Утверждение, что транзакций в MongoDB нет вообще (устаревшая информация)
  • Игнорирование требования replica set для транзакций
  • Использование транзакций для операций, которые можно сделать атомарно на одном документе
  • Отсутствие обработки transient transaction errors (write conflicts требуют retry)
  • Смешивание транзакций с операциями, изменяющими схему (DDL внутри транзакции не поддерживается)

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью