← Назад к вопросам
Что такое уровни изоляции транзакций в 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 Read | Non-repeatable | Phantom | Скорость |
|---|---|---|---|---|
| READ UNCOMMITTED | Yes | Yes | Yes | Макс |
| READ COMMITTED | No | Yes | Yes | Хорошо |
| REPEATABLE READ | No | No | Yes | Средняя |
| SERIALIZABLE | No | No | No | Минимум |
В 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.