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

Как работали оптимистичные блокировки в Postgres?

Компании, где спрашивали
КасперскийКасперский

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

sobes.tech AI

Оптимистичные блокировки в PostgreSQL обычно реализуются с помощью механизма версионирования строк (MVCC) и поля, хранящего версию или временную метку.

Идея в том, что при чтении данных мы не ставим блокировку, а при обновлении проверяем, что данные не изменились с момента чтения. Если изменились — операция откатывается или повторяется.

В Go это можно реализовать так:

  • При выборке данных читаем поле версии (например, xmin или пользовательское поле version).
  • При обновлении в SQL пишем условие WHERE id = ? AND version = ?.
  • Если обновление затронуло 0 строк — значит, данные изменились, и нужно обработать конфликт.

Пример SQL:

UPDATE table SET data = $1, version = version + 1 WHERE id = $2 AND version = $3;

В Go коде это выглядит примерно так:

result, err := db.ExecContext(ctx, "UPDATE table SET data = $1, version = version + 1 WHERE id = $2 AND version = $3", newData, id, oldVersion)
rowsAffected, _ := result.RowsAffected()
if rowsAffected == 0 {
    // Обработка конфликта — повторить или вернуть ошибку
}

Таким образом, оптимистичная блокировка позволяет избежать блокировок на чтение и минимизировать конфликты при конкурентных обновлениях.