← Назад к вопросам

Что такое уровни изоляции транзакций в SQL?

1.0 Junior🔥 171 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое уровни изоляции транзакций в SQL?

Уровни изоляции определяют, как одновременные транзакции видят друг друга при доступе к одним и тем же данным. Это компромисс между безопасностью и производительностью.

Четыре уровня (от слабого к сильному)

1. READ UNCOMMITTED — самый слабый

  • Читаешь НЕ зафиксированные данные
  • Проблема: Dirty Read (грязное чтение)
  • Очень редко используется
TRANSACTION 1:
UPDATE Accounts SET Balance = 900 WHERE Id = 1;
-- Не закоммитил

TRANSACTION 2 (с READ UNCOMMITTED):
SELECT Balance FROM Accounts WHERE Id = 1;  -- Видит 900!

TRANSACTION 1:
ROLLBACK;  -- Откатился, а Transaction 2 прочитала неправильное значение

2. READ COMMITTED — стандарт

  • Видишь только зафиксированные изменения
  • Проблема: Non-repeatable Read
  • Используется по умолчанию в SQL Server
TRANSACTION 1:
BEGIN;
SELECT Balance FROM Accounts WHERE Id = 1;  -- 1000

TRANSACTION 2:
UPDATE Accounts SET Balance = 500 WHERE Id = 1;
COMMIT;

TRANSACTION 1:
SELECT Balance FROM Accounts WHERE Id = 1;  -- Теперь 500! (изменилось)
COMMIT;

3. REPEATABLE READ — повторяемое

  • Значение строки не меняется в рамках транзакции
  • Проблема: Phantom Read (новые строки)
TRANSACTION 1:
BEGIN;
SELECT * FROM Users WHERE Status = 'active';  -- 5 пользователей

TRANSACTION 2:
INSERT INTO Users VALUES (6, 'John', 'active');
COMMIT;

TRANSACTION 1:
SELECT * FROM Users WHERE Status = 'active';  -- 6 пользователей! (phantom)
COMMIT;

4. SERIALIZABLE — максимальный

  • Полная изоляция
  • Транзакции выполняются как последовательные
  • Очень медленно

Таблица проблем

УровеньDirty ReadNon-repeatablePhantomСкорость
READ UNCOMMITTEDYesYesYesМакс
READ COMMITTEDNoYesYesХорошо
REPEATABLE READNoNoYesСредняя
SERIALIZABLENoNoNoМинимум

В C# / EF Core

// По умолчанию: READ COMMITTED
public async Task GetUserAsync(int id)
{
    using (var transaction = _context.Database.BeginTransaction(
        IsolationLevel.ReadCommitted))
    {
        var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == id);
        await transaction.CommitAsync();
        return user;
    }
}

// Для денежных операций: SERIALIZABLE
public async Task WithdrawAsync(int accountId, decimal amount)
{
    using (var transaction = _context.Database.BeginTransaction(
        IsolationLevel.Serializable))
    {
        var account = await _context.Accounts
            .FirstOrDefaultAsync(a => a.Id == accountId);
        
        if (account.Balance < amount)
            throw new InvalidOperationException();
        
        account.Balance -= amount;
        await _context.SaveChangesAsync();
        await transaction.CommitAsync();
    }
}

Когда какой использовать?

  • READ COMMITTED (по умолчанию) — обычные операции
  • REPEATABLE READ — когда нужна консистентность одной строки
  • SERIALIZABLE — критичные операции (платежи, транзакции)
  • READ UNCOMMITTED — почти никогда

Альтернатива: Optimistic Concurrency

Вместо блокировок используй версионирование:

public class Account
{
    public int Id { get; set; }
    public decimal Balance { get; set; }
    
    [ConcurrencyCheck]
    [Timestamp]
    public byte[] RowVersion { get; set; }
}

// EF Core автоматически проверяет версию при обновлении
await _context.SaveChangesAsync();  // Выбросит DbUpdateConcurrencyException если версия изменилась

Итого

Уровни изоляции — это компромисс:

  • Слабые уровни — быстрые, но могут быть ошибки данных
  • Сильные уровни — безопасные, но медленные

В 99% случаев используй READ COMMITTED (по умолчанию). Для критичных операций — SERIALIZABLE или Optimistic Concurrency.

Что такое уровни изоляции транзакций в SQL? | PrepBro