Ответ
В Go режимы работы транзакций в пакете database/sql
настраиваются с помощью структуры sql.TxOptions
при её создании. Ключевые параметры — это уровень изоляции и флаг "только для чтения".
// Контекст для управления временем жизни транзакции
ctx := context.Background()
// Опции для транзакции
opts := &sql.TxOptions{
// Уровень изоляции. sql.LevelDefault использует настройки по умолчанию для СУБД.
Isolation: sql.LevelSerializable,
// Флаг, указывающий, что транзакция не будет изменять данные.
ReadOnly: false,
}
// Начало транзакции с заданными опциями
tx, err := db.BeginTx(ctx, opts)
if err != nil {
log.Fatal(err)
}
// Не забудьте откатить транзакцию в случае ошибки
// tx.Commit() или tx.Rollback()
Уровни изоляции
Стандартные уровни изоляции, доступные в Go, определяют, как транзакции "видят" изменения, сделанные другими параллельными транзакциями:
LevelDefault
: Используется уровень по умолчанию, установленный в самой базе данных.LevelReadUncommitted
: "Грязное чтение". Транзакция может читать незафиксированные (uncommitted) изменения других транзакций. Самый быстрый, но наименее безопасный уровень.LevelReadCommitted
: "Чтение зафиксированных данных". Транзакция видит только те изменения, которые уже были зафиксированы (committed). Предотвращает "грязное чтение".LevelRepeatableRead
: "Повторяемое чтение". Гарантирует, что при повторном чтении одних и тех же данных в рамках одной транзакции результат будет одинаковым. Предотвращает "неповторяемое чтение".LevelSerializable
: "Сериализуемость". Самый строгий уровень. Гарантирует, что результат параллельного выполнения транзакций будет таким же, как если бы они выполнялись последовательно. Предотвращает все аномалии, включая "фантомное чтение".
Флаг ReadOnly
Установка ReadOnly: true
сообщает базе данных, что транзакция не будет вносить изменения. Некоторые СУБД могут использовать это для оптимизации производительности, например, направляя запросы на реплику для чтения.
Выбор уровня изоляции — это всегда компромисс между согласованностью данных и производительностью.