Как работает уровень изоляции транзакций Read Committed?

Ответ

Read Committed — это один из стандартных уровней изоляции транзакций в базах данных. Его основное правило: транзакция видит только те данные, которые были зафиксированы (committed) до её начала.

Принцип работы:
Каждый SQL-запрос в рамках транзакции видит "снимок" данных на момент начала этого запроса, а не всей транзакции. Это защищает от чтения "грязных" (незафиксированных) данных.

Какие проблемы решает и допускает:

  • Решает проблему "Грязного чтения" (Dirty Read): Вы не сможете прочитать данные, которые другая транзакция изменила, но еще не зафиксировала.
  • Допускает "Неповторяемое чтение" (Non-Repeatable Read): Если между двумя одинаковыми SELECT в вашей транзакции другая транзакция успеет изменить и зафиксировать данные, то результаты двух SELECT будут отличаться.
  • Допускает "Фантомное чтение" (Phantom Read): Другая транзакция может добавить новые строки, которые попадут под условие вашего SELECT, и при повторном выполнении вы увидите эти "фантомные" строки.

Пример в Go (с использованием database/sql):
Идиоматичный способ установить уровень изоляции — через опции при старте транзакции.

// ctx - это context.Context
opts := &sql.TxOptions{Isolation: sql.LevelReadCommitted}

tx, err := db.BeginTx(ctx, opts)
if err != nil {
    log.Fatal(err)
}

// Все запросы внутри этой транзакции (tx) будут выполняться
// с уровнем изоляции Read Committed.
_, err = tx.Query("SELECT balance FROM accounts WHERE id = ?", 1)
// ...
tx.Commit()

Read Committed является уровнем изоляции по умолчанию во многих СУБД (например, PostgreSQL, Oracle) и предлагает хороший баланс между производительностью и согласованностью данных.