Ответ
В стандарте SQL и, в частности, в PostgreSQL, определены четыре основных уровня изоляции транзакций. Каждый следующий уровень предотвращает определенные аномалии конкурентного доступа (феномены чтения).
Read Uncommitted (Чтение незафиксированных данных)
- Позволяет читать незафиксированные ("грязные") данные других транзакций.
- Возможные аномалии: Dirty Read, Non-Repeatable Read, Phantom Read.
- В PostgreSQL этот уровень работает как
Read Committed
.
Read Committed (Чтение зафиксированных данных)
- Транзакция видит только те данные, которые были зафиксированы до ее начала. Каждый новый запрос в транзакции видит свежие зафиксированные данные.
- Возможные аномалии: Non-Repeatable Read, Phantom Read.
- Это уровень по умолчанию в PostgreSQL.
Repeatable Read (Повторяемое чтение)
- Гарантирует, что при повторном чтении в рамках одной транзакции данные будут теми же, даже если другие транзакции их изменили и зафиксировали.
- Возможные аномалии: Phantom Read.
Serializable (Сериализуемый)
- Самый строгий уровень. Гарантирует, что результат параллельного выполнения транзакций будет таким же, как если бы они выполнялись последовательно. Предотвращает все аномалии.
Пример установки уровня изоляции в Go при работе с database/sql
:
// Установка уровня изоляции для следующей транзакции
// Вариант 1: через SQL-запрос
db.ExecContext(ctx, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")
// Вариант 2: через опции при старте транзакции (предпочтительнее)
tx, err := db.BeginTx(ctx, &sql.TxOptions{
Isolation: sql.LevelSerializable, // Используем константу из пакета sql
})
if err != nil {
log.Fatal(err)
}
// ... работа с транзакцией tx