Time line
- 44:25
- 25:23
Транзакция - логическая единица работы, удовлетворяющая след. 4-м свойствам (ACID)
- Атомарность (Atomicity) - в транзакции выполняется все или ничего; транзакция не может выполниться частично
- Согласованность (Consistentcy) - транзакция переводит базу данных из одного согласованного состояния в другое согласованное состояние
- Изолированность (Isolation) - каждая транзакция выполняется вне зависимости от других транзакций
- Долговечность (Durability) - если изменения состояния базы данных, сделанные транзакцией, зафиксированны, то они будут сохранены даже если потом произойдет сбой
Транзакция нужна в первую очередь чтобы обеспечить предсказуемый результат!
Пример создания транзакции
create table films (
imdb varchar(16) primary key,
title varchar(40) not null,
kind varchar(10)
);
CREATE TABLE
Начало транзакции
begin;
BEGIN
Обработка данных внутри транзакции
insert into films (imdb, title, kind) values
(1234, 'Выживший', 'вестерн');
INSERT 0 1
Успешное завершение транзакции
commit;
COMMIT
Проверка что данные после транзакции не потерялись
TABLE films;
imdb | title | kind
------+----------+---------
1234 | Выживший | вестерн
(1 row)
Журнал транзакций (WAL файлы)
Бонус журналов транзакций
На базе журнала транзакций реализуется ряд дополнительных возможностей
- Point in time recovery - восстановление по журналу транзакций
- Репликация - если есть две одинаковые копии БД, то с помощью WAL файлов можно обеспечить их синхронизацию. В одной БД WAL файлы создаються и по сети (rsync) передаються в копию.
Изолированность. Мультиверсионность. MVCC
Номер транзакции - отметка времени
- xmin - номер транзакции которая создала версию строки
- xmax - номер транзакции которая удалила версию строки
Пример блокировки транзакции
create table accounts (
id int,
name varchar,
balance int
);
CREATE TABLE
insert into accounts
(id, name, balance) values
( 1, 'Alice', 500 );
INSERT 0 1
TABLE accounts;
id | name | balance
----+-------+---------
1 | Alice | 500
(1 row)
Транзакция №1
BEGIN TRANSACTION
ISOLATION LEVEL REPEATABLE READ;
BEGIN
SELECT balance
FROM accounts
WHERE name = 'Alice';
balance
---------
500
(1 row)
UPDATE accounts
SET balance = balance + 100
WHERE name = 'Alice';
UPDATE 1
Транзакция №2
BEGIN TRANSACTION
ISOLATION LEVEL REPEATABLE READ;
BEGIN
SELECT balance
FROM accounts
WHERE name = 'Alice';
balance
---------
500
(1 row)
UPDATE accounts
SET balance = balance + 500
WHERE name = 'Alice';
Update висит пока 1-я транзакция сделает либо commit либо rollback
1) Если Транзакция №1 делает commit
, то Транзакция №2 падает с ошибкой
ERROR: could not serialize access due to concurrent update
Более того, после этой ошибки вообще ничего сделать не получится, пока не сделаешь rollback
select 1;
ERROR: current transaction is aborted, commands ignored until end of transaction block
2) Если Транзакция №1 делает rollback
, то Транзакция №2 завершается успешно
UPDATE 1
Уровни изолированности транзакции
- Read uncommited - чтение незафиксированных данных
- Read commited (по умолчанию) - чтение фиксированных данных
- Repeatable read - повторяемость чтения
- Serializable - упорядочиваемость