Ответ
READ COMMITTED — это второй по строгости (после READ UNCOMMITTED) уровень изоляции транзакций в SQL. Его основная гарантия: транзакция видит только те данные, которые были зафиксированы другими транзакциями на момент выполнения каждого её оператора чтения.
Гарантии и аномалии:
| Аномалия | Разрешена в READ COMMITTED? | Описание |
|---|---|---|
| Грязное чтение (Dirty Read) | Нет | Чтение незафиксированных данных другой транзакции. |
| Неповторяющееся чтение (Non-repeatable Read) | Да | Получение разных значений одного и того же поля при повторном чтении в рамках одной транзакции. |
| Фантомное чтение (Phantom Read) | Да | Появление новых строк при повторном выполнении запроса с тем же условием. |
Как это работает: СУБД обычно блокирует считываемые строки (или использует механизм управления версиями, как в PostgreSQL и Oracle) на время текущего оператора SELECT, предотвращая чтение незафиксированных изменений. После выполнения оператора блокировка снимается.
Пример (PostgreSQL):
-- Сессия 1
BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- Пока не выполнен COMMIT, изменения НЕ видны в Сессии 2.
-- Сессия 2 (параллельно)
BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT balance FROM accounts WHERE id = 1; -- Видит старое значение (например, 1000)
-- Сессия 1
COMMIT; -- Фиксирует изменение (balance = 900)
-- Сессия 2
SELECT balance FROM accounts WHERE id = 1; -- Теперь видит новое зафиксированное значение (900) -> Неповторяющееся чтение!
COMMIT;
Использование в Java (JDBC):
Connection conn = dataSource.getConnection();
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
Когда использовать? READ COMMITTED — это разумный компромисс по умолчанию для многих приложений. Он обеспечивает защиту от грязных чтений (самой критичной аномалии) и сохраняет высокую производительность за счёт допущения неповторяющихся и фантомных чтений.