Ответ
PostgreSQL не реализует уровень изоляции READ UNCOMMITTED (чтение незафиксированных данных) из-за своей архитектуры MVCC (Multiversion Concurrency Control). В этой модели каждый запрос видит снимок данных (snapshot) на момент своего начала, что физически исключает возможность чтения "грязных" данных из незавершённых транзакций.
Как это работает:
- При любом
SELECTсистема обращается к согласованному снимку, а не к непосредственно изменяемым страницам данных. - Если вы явно укажете
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;, PostgreSQL тихо понизит его доREAD COMMITTED(чтение зафиксированных данных) — минимального доступного уровня.
Пример на C# с Npgsql:
using var connection = new NpgsqlConnection(connectionString);
await connection.OpenAsync();
// Попытка установить ReadUncommitted
using var transaction = await connection.BeginTransactionAsync(
IsolationLevel.ReadUncommitted // Будет проигнорирован
);
var command = new NpgsqlCommand("SELECT balance FROM accounts WHERE id = 1", connection, transaction);
var balance = await command.ExecuteScalarAsync();
// Здесь balance будет взят из снимка READ COMMITTED,
// а не из незавершённой транзакции другого пользователя.
Почему это осознанный выбор:
- Целостность данных: Гарантируется, что приложение никогда не прочитает данные, которые могут быть откатаны, что предотвращает логические ошибки.
- Производительность: MVCC позволяет выполнять чтение без блокировок, даже при наличии параллельных пишущих транзакций, что хорошо для OLTP-нагрузки.
- Упрощение модели: Разработчикам не нужно думать о последствиях чтения "грязных" данных, так как этот сценарий невозможен.
Если вам нужно читать данные без ожидания завершения других транзакций, в PostgreSQL для этого используется уровень READ COMMITTED в сочетании с MVCC.