Мое понимание уровня изоляции транзакции REPEATABLE READ
заключается в том, что после его установки данные, прочитанные в транзакции, не изменятся. Я использовал следующий код, чтобы проверить это:
ctx = context.Background()
tx, _ := db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable})
time.Sleep(5 * time.Second)
// do query on tx
Пока процесс спит, я через консоль вставил еще одну запись. Но в результатах появилась вновь вставленная запись. Почему это так? Я не хочу читать записи, вставленные после начала транзакции. Я также пробовал:
tx, _ := db.Begin()
_, err = tx.Exec(`set transaction isolation level repeatable read;`)
Но все равно результаты те же.
Снимок транзакции REPEATABLE READ
или SERIALIZABLE
делается не в момент ее запуска, а при выполнении первого оператора SQL внутри транзакции.
Во-первых, это оптимизация для случая, когда транзакция вообще не выполняет никаких инструкций. Во-вторых, это единственный способ разрешить установку уровня изоляции транзакции после в начале транзакции, но до любой оператор SQL был запущен с
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Я ожидаю, что это будет
BEGIN ISOLATION LEVEL SERIALIZABLE
, который устанавливает уровень изоляции сразу при запуске транзакции.