← Назад к вопросам

Поддерживает MongoDB транзакции

1.3 Junior🔥 141 комментариев
#Базы данных (NoSQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Поддержка транзакций в MongoDB

Да, MongoDB полностью поддерживает транзакции, но с определёнными ограничениями и особенностями. Это важное изменение в архитектуре базы данных, которое произошло в MongoDB 4.0.

История поддержки транзакций

  • MongoDB 4.0 (июль 2018): Добавлена поддержка single-document ACID транзакций
  • MongoDB 4.2 (август 2019): Поддержка multi-document транзакций с синтаксисом сессий
  • MongoDB 5.0+: Улучшения и оптимизация транзакций

Tipos транзакций

1. Single-Document ACID Транзакции Ключевое преимущество MongoDB — атомарность операций на уровне одного документа.

from pymongo import MongoClient

client = MongoClient()
db = client[store]

# Атомарная операция на одном документе
db.accounts.update_one(
    {_id: account123},
    {: {balance: -100}}
)

2. Multi-Document Транзакции Начиная с MongoDB 4.2, можно использовать транзакции для изменения нескольких документов в разных коллекциях.

from pymongo import MongoClient
from pymongo.errors import OperationFailure

client = MongoClient()
session = client.start_session()

try:
    session.start_transaction()
    
    # Операция 1: вычесть сумму со счёта
    db.accounts.update_one(
        {_id: account1},
        {: {balance: -100}},
        session=session
    )
    
    # Операция 2: добавить сумму на другой счёт
    db.accounts.update_one(
        {_id: account2},
        {: {balance: 100}},
        session=session
    )
    
    session.commit_transaction()
    print("Транзакция успешна")
    
except OperationFailure as e:
    session.abort_transaction()
    print(f"Ошибка: {e}")
finally:
    session.end_session()

Свойства ACID в MongoDB

A — Atomicity (Атомарность)

  • Все операции в транзакции либо выполнены полностью, либо откачены полностью
  • Нет частичных результатов

C — Consistency (Консистентность)

  • Данные остаются в валидном состоянии после каждой транзакции
  • Валидация данных происходит на уровне приложения

I — Isolation (Изолированность)

  • Используется Snapshot Isolation (SI)
  • Транзакция видит снимок БД на момент старта
  • Не видит изменений других параллельных транзакций

D — Durability (Надёжность)

  • После commit, данные гарантированно сохранены
  • Даже при сбое сервера

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

# ❌ ОГРАНИЧЕНИЕ 1: Только для Replica Set или Sharded Cluster
# Транзакции недоступны на Standalone инстансе

# ❌ ОГРАНИЧЕНИЕ 2: Максимальный размер
# Все изменения в транзакции ограничены 16 МБ

# ❌ ОГРАНИЧЕНИЕ 3: Операции DDL запрещены
# Нельзя создавать/удалять коллекции или индексы внутри транзакции

# ❌ ОГРАНИЧЕНИЕ 4: Задержка на большие наборы данных
client = MongoClient()
session = client.start_session()

try:
    session.start_transaction()
    
    # ❌ Плохо: очень большой batch
    large_batch = list(db.orders.find({status: pending}).limit(100000))
    
    session.commit_transaction()
except:
    session.abort_transaction()
finally:
    session.end_session()

Правильное использование транзакций

from contextlib import contextmanager
from pymongo.errors import OperationFailure

@contextmanager
def transaction(client):
    """Context manager для безопасной работы с транзакциями"""
    session = client.start_session()
    try:
        session.start_transaction()
        yield session
        session.commit_transaction()
    except OperationFailure as e:
        session.abort_transaction()
        raise
    finally:
        session.end_session()

# Использование
client = MongoClient()
db = client[store]

try:
    with transaction(client) as session:
        # Перевод денег между счётами
        db.accounts.update_one(
            {_id: user1},
            {: {balance: -50}},
            session=session
        )
        db.accounts.update_one(
            {_id: user2},
            {: {balance: 50}},
            session=session
        )
        # История платежа
        db.payments.insert_one(
            {from: user1, to: user2, amount: 50},
            session=session
        )
        print("Успешно")
except Exception as e:
    print(f"Ошибка: {e}")

Когда использовать транзакции

✅ Используй:

  • Переводы денег между счётами
  • Создание заказа с уменьшением инвентаря
  • Синхронизация связанных данных
  • Критичные бизнес-операции

❌ Не используй:

  • Простые вставки одного документа
  • Чтение данных
  • Операции, которые занимают очень долго
  • Если данные могут быть консистентны на уровне документа

Альтернатива транзакциям

Для случаев, когда транзакции недоступны, используй:

# Event Sourcing подход
db.payments.insert_one({
    type: transfer,
    from: user1,
    to: user2,
    amount: 50,
    status: completed,
    timestamp: datetime.utcnow()
})

# Idempotency keys для безопасности
db.orders.update_one(
    {idempotency_key: abc123},
    {: {items: [...]}},
    upsert=True
)

Заключение

MongoDB полностью поддерживает ACID транзакции с версии 4.0, что делает её полноценной БД для критичных систем. Однако нужно понимать ограничения и правильно выбирать сценарии использования транзакций.

Поддерживает MongoDB транзакции | PrepBro