Установка и тестирование уровней изоляции (Isolation Levels)
В этом шаге вы узнаете об уровнях изоляции транзакций (transaction isolation levels) в PostgreSQL, а также о том, как их устанавливать и тестировать. Уровни изоляции контролируют степень, в которой параллельные транзакции изолированы друг от друга. Более высокие уровни изоляции обеспечивают большую защиту от повреждения данных, но могут снизить параллелизм (concurrency).
Вы должны быть по-прежнему подключены к базе данных PostgreSQL с предыдущего шага. Если нет, подключитесь снова, используя:
sudo -u postgres psql
Откройте два отдельных окна терминала. В каждом терминале подключитесь к базе данных PostgreSQL от имени пользователя postgres
. У вас должно быть два приглашения postgres=#
.
Терминал 1:
sudo -u postgres psql
Терминал 2:
sudo -u postgres psql
В Терминале 1 установите уровень изоляции READ COMMITTED
(хотя это значение по умолчанию, мы установим его явно для демонстрации).
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Затем начните транзакцию.
BEGIN;
В Терминале 1 прочитайте баланс Alice.
SELECT balance FROM accounts WHERE name = 'Alice';
Запомните баланс. Теперь в Терминале 2 начните транзакцию и обновите баланс Alice.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
UPDATE accounts SET balance = 90.00 WHERE name = 'Alice';
COMMIT;
В Терминале 1 прочитайте баланс Alice еще раз.
SELECT balance FROM accounts WHERE name = 'Alice';
Поскольку уровень изоляции — READ COMMITTED
, вы увидите обновленный баланс (90.00), зафиксированный (committed) Терминалом 2.
Теперь давайте протестируем уровень изоляции REPEATABLE READ
. В Терминале 1 откатите (roll back) текущую транзакцию и установите уровень изоляции REPEATABLE READ
.
ROLLBACK;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
В Терминале 1 прочитайте баланс Alice еще раз.
SELECT balance FROM accounts WHERE name = 'Alice';
Запомните баланс. Теперь в Терминале 2 начните транзакцию и снова обновите баланс Alice.
BEGIN;
UPDATE accounts SET balance = 100.00 WHERE name = 'Alice';
COMMIT;
В Терминале 1 прочитайте баланс Alice еще раз.
SELECT balance FROM accounts WHERE name = 'Alice';
Поскольку уровень изоляции — REPEATABLE READ
, вы по-прежнему будете видеть исходный баланс с момента начала транзакции, даже если Терминал 2 зафиксировал (committed) новое значение.
Наконец, в Терминале 1 зафиксируйте (commit) транзакцию.
COMMIT;
Теперь, если вы снова прочитаете баланс Alice в Терминале 1, вы увидите последнее зафиксированное (committed) значение (100.00).
Выйдите из обеих оболочек psql
.
\q