Sobes.tech
Middle
45

¿Cómo manejas la condición de carrera al escribir en la base de datos sin usar transacciones?

Empresas donde se preguntó
ИП Ганус Александр Андреевич

Respuesta de la IA

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()

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