Ответ
Repeatable Read — это уровень изоляции транзакций, при котором в рамках одной транзакции гарантируется, что повторные чтения одних и тех же данных вернут одинаковые результаты, даже если другие транзакции пытаются изменить эти данные. Однако новые строки, добавленные другими транзакциями, могут быть видны (фантомное чтение).
В Go (с использованием database/sql и PostgreSQL):
tx, err := db.BeginTx(ctx, &sql.TxOptions{
Isolation: sql.LevelRepeatableRead,
})
if err != nil {
log.Fatal(err)
}
defer tx.Rollback()
// Первое чтение
var balance int
err = tx.QueryRow("SELECT balance FROM accounts WHERE id = 1").Scan(&balance)
// Другая транзакция может изменить balance, но здесь мы всё равно увидим старое значение
err = tx.QueryRow("SELECT balance FROM accounts WHERE id = 1").Scan(&balance)
Ключевые особенности:
- Защищает от "грязного" и неповторяющегося чтения
- Не защищает от фантомного чтения
- В случае конфликта (например, параллельное изменение данных) может возникнуть ошибка сериализации (в PostgreSQL)