Уровни изоляции транзакций являются ключевым аспектом реляционных баз данных, включая PostgreSQL. Они определяют, как данные изолируются друг от друга при выполнении параллельных транзакций, обеспечивая согласованность и целостность данных. PostgreSQL поддерживает стандартные уровни изоляции, определенные ANSI SQL, а также дополнительные режимы, обеспечивая гибкость и оптимизацию работы с данными. Уровни называются во взаимосвязи с аномалиями, которые допускаются или нет на том или другом уровне изоляции:
Уровни изоляции и их особенности:
- READ UNCOMMITTED (Чтение неподтвержденных данных): Наименьший уровень изоляции, где транзакции видят неподтвержденные изменения других транзакций. Этот уровень обеспечивает максимальную параллельность, но может привести к непредсказуемым результатам из-за “грязного чтения”.
- READ COMMITTED (Чтение подтвержденных данных): Большинство баз данных, включая PostgreSQL, используют этот уровень по умолчанию. Транзакции видят только подтвержденные изменения других транзакций. Это предотвращает “грязное чтение”, но допускает “неповторяющееся чтение”.
- REPEATABLE READ (Повторяемое чтение): В этом режиме транзакции видят только данные, которые были считаны на момент начала транзакции. Это предотвращает “грязное чтение” и “неповторяющееся чтение”, но может привести к “фантомным” записям, когда другая транзакция вставляет новые записи.
- SERIALIZABLE (Сериализуемость): Самый строгий уровень изоляции. Транзакции выполняются так, как если бы они выполнялись последовательно. Это предотвращает “грязное чтение”, “неповторяющееся чтение” и “фантомные” записи. Однако это может привести к блокировкам и ухудшению производительности.
Выбор уровня изоляции:
Выбор уровня изоляции зависит от требований к согласованности данных и производительности. Более строгие уровни изоляции обеспечивают более высокую согласованность, но могут привести к блокировкам и ухудшению производительности. В то время как менее строгие уровни обеспечивают большую параллельность, но могут привести к непредсказуемым результатам.
Изменение уровня изоляции в PostgreSQL:
Вы можете изменить уровень изоляции для текущей транзакции с помощью команды SET TRANSACTION ISOLATION LEVEL
.
Второй вариант – сразу начать транзакцию на нужном уровне изоляции, например:
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Уровни изоляции транзакций в PostgreSQL предоставляют средства для балансировки между согласованностью и производительностью при работе с данными. Выбор правильного уровня изоляции зависит от конкретных требований вашего приложения и ожидаемых характеристик работы с данными. Важно понимать особенности каждого уровня и тщательно анализировать, как он будет взаимодействовать с вашими данными и запросами.
Посмотрим на практике:
Подключимся одновременно с двух сеансов к одному инстансу PostgreSQL и в первой сессии выполним команды:
CREATE TABLE test (i serial, amount int);
INSERT INTO test(amount) VALUES (1);
INSERT INTO test(amount) VALUES (2);
show transaction isolation level;
CREATE TABLE
postgres=# INSERT INTO test(amount) VALUES (1);
INSERT 0 1
postgres=# INSERT INTO test(amount) VALUES (2);
INSERT 0 1
postgres=# show transaction isolation level;
transaction_isolation
read committed
(1 row)
И начнем транзакцию на стандартном уровне изоляции PostgreSQL – READ COMMITTED:
BEGIN;
SELECT * FROM test;
i | amount
—+——–
1 | 1
2 | 2
(2 rows)
Выполним команды из 2 консоли:
BEGIN;
UPDATE test set amount = 3 WHERE i = 1;
COMMIT;
Проверим еще раз состояние в первой консоли:
SELECT * FROM test;
COMMIT;
i | amount
—+——–
2 | 2
1 | 3
(2 rows)
Видим другое значение в той же транзакции – наблюдаем ситуацию неповторяющегося чтения.
Теперь посмотрим как себя поведет PostgreSQL на уровне изоляции REPEATABLE READ:
В 1 консоли выполним:
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT * FROM test;
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN
SELECT * FROM test;
i | amount
—+——–
2 | 2
1 | 3
(2 rows)
Во второй консоли:
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
INSERT INTO test VALUES (8);
COMMIT;
И прочитаем еще раз данные из первой консоли:
SELECT * FROM test;
i | amount
—+——–
2 | 2
1 | 3
(2 rows)
Видим, что аномалии “фантомное чтение” мы не наблюдаем.
Итоги:
В зависимости от установленного уровня изоляции мы можем наблюдать те или иные аномалии. Повышение уровня изоляции несет за собой дополнительные издержки, но позволяет исключить аномалии доступа к данным. Выше уровня REPEATABLE READ особо смысла увеличить нет.
Более подробно про Уровни изоляций в моём видео на ютуб.
Больше про транзакции в моей статье
Добавить комментарий