Sobes.tech
Назад к вопросам
Middle
3

Как работаешь с race condition при записи в БД без использования транзакций?

Компании, где спрашивали
ИП Ганус Александр Андреевич

Ответ от нейросети

sobes.tech AI

При работе с race condition без транзакций можно использовать несколько подходов:

  • Оптимистичная блокировка: хранить версию записи (например, поле version или timestamp). При обновлении проверять, что версия не изменилась с момента чтения. Если изменилась — повторить операцию.

  • Использование уникальных ограничений и проверок на уровне БД: например, попытка вставить запись с уникальным ключом, если конфликт — обработать ошибку и повторить.

  • Явное блокирование на уровне приложения: использовать mutex или lock в коде, чтобы только один поток/процесс мог писать в БД в данный момент.

  • Использование atomic операций БД: если СУБД поддерживает, применять команды типа INSERT ... ON CONFLICT или UPDATE ... WHERE version = ?.

Пример оптимистичной блокировки на Python с SQLAlchemy:

from sqlalchemy import update

# Читаем запись с версией
record = session.query(MyModel).filter_by(id=record_id).one()
current_version = record.version

# Пытаемся обновить с проверкой версии
stmt = update(MyModel).where(
    MyModel.id == record_id,
    MyModel.version == current_version
).values(data=new_data, version=current_version + 1)

result = session.execute(stmt)
if result.rowcount == 0:
    # Конфликт, версия изменилась — повторить или обработать ошибку
    pass
else:
    session.commit()

Такой подход помогает избежать потери данных при одновременных записях без использования транзакций.