Академический Документы
Профессиональный Документы
Культура Документы
Транзакции.
Окулов Антон
R.class
Определение
Транзакция (англ. transaction, от лат. transactio — соглашение, договор) —
минимальная логически осмысленная операция, которая имеет смысл и
может быть совершена только полностью.
Определение
Транзакция (англ. transaction, от лат. transactio — соглашение, договор) —
минимальная логически осмысленная операция, которая имеет смысл и
может быть совершена только полностью.
- И т.д.
ACID
- это требования к транзакционной системе (например, к СУБД),
обеспечивающие наиболее надёжную и предсказуемую её работу.
Требования ACID были в основном сформулированы в конце 70-х годов
Джимом Греем.
ACID
- это требования к транзакционной системе (например, к СУБД),
обеспечивающие наиболее надёжную и предсказуемую её работу.
Требования ACID были в основном сформулированы в конце 70-х годов
Джимом Греем.
ACID
- Atomicity — Атомарность
- Consistency — Согласованность
- Isolation — Изолированность
- Durability — Стойкость
ACID
- Atomicity — Атомарность - Атомарность гарантирует, что никакая
транзакция не будет зафиксирована в системе частично. Будут либо
выполнены все её подоперации, либо не выполнено ни одной.
ACID
- Atomicity — Атомарность - Атомарность гарантирует, что никакая
транзакция не будет зафиксирована в системе частично. Будут либо
выполнены все её подоперации, либо не выполнено ни одной.
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
COMMIT;
Пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
COMMIT;
Пример
BEGIN;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
COMMIT;
Пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
COMMIT;
Пример - откат
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
ROLLBACK;
Пример - savepoint
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
SAVEPOINT before_charging;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
ROLLBACK TO before_charging;
Пример - savepoint
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
SAVEPOINT before_charging;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
ROLLBACK;
Пример - savepoint
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
SAVEPOINT before_charging;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
COMMIT;
Уровни изоляции
- READ UNCOMMITTED - транзакции видят результаты других
незавершенных транзакций.
`balance`.`sum` = 1
FOR SHARE - пример
START TRANSACTION;
`balance`.`sum` = 1
FOR SHARE - пример
START TRANSACTION;
`balance`.`sum` = 1 `balance`.`sum` = 1
FOR SHARE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
FOR SHARE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
COMMIT; WHERE `balance`.`user_id` = 1;
FOR SHARE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
COMMIT; WHERE `balance`.`user_id` = 1;
COMMIT;
FOR SHARE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
COMMIT; WHERE `balance`.`user_id` = 1;
COMMIT;
`balance`.`sum` = 2
FOR UPDATE - пример
START TRANSACTION;
`balance`.`sum` = 1
FOR UPDATE - пример
START TRANSACTION;
Ожидание ...
FOR UPDATE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
Ожидание ...
FOR UPDATE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1; Ожидание ...
COMMIT;
FOR UPDATE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
COMMIT;
`balance`.`sum` = 2
FOR UPDATE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
COMMIT;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
FOR UPDATE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
COMMIT;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
COMMIT;
FOR UPDATE - пример
START TRANSACTION;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
COMMIT;
UPDATE `balance`
SET `balance`.`sum` = :prev_balance + 1
WHERE `balance`.`user_id` = 1;
COMMIT;
`balance`.`sum` = 3
LOCK TABLES
LOCK TABLES `balance`;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
UNLOCK TABLES;
LOCK TABLES
LOCK TABLES `balance` READ, `users` WRITE;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
UNLOCK TABLES;
LOCK TABLES - опасно и устарело
LOCK TABLES `balance` READ, `users` WRITE;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` - 100
WHERE `balance`.`user_id` = 1;
UPDATE `balance`
SET `balance`.`sum` = `balance`.`sum` + 100
WHERE `balance`.`user_id` = 2;
UNLOCK TABLES;
AUTOCOMMIT
-- Эти изменения сразу запишутся на диск
INSERT INTO `balance` (`sum`, `user_id`) VALUES (100, 1);
AUTOCOMMIT
-- Эти изменения сразу запишутся на диск
INSERT INTO `balance` (`sum`, `user_id`) VALUES (100, 1);
-- Запишем изменения
COMMIT;
AUTOCOMMIT
-- Эти изменения сразу запишутся на диск
INSERT INTO `balance` (`sum`, `user_id`) VALUES (100, 1);
-- Запишем изменения
COMMIT;
COMMIT; COMMIT;
DEADLOCK
START TRANSACTION; START TRANSACTION;
COMMIT; COMMIT;
- При этом при отказе системы - у нас есть все изменения и мы можем
их “проиграть” из WAL
Почитать?
https://ru.wikipedia.org/wiki/ACID
https://habr.com/ru/post/469415/
https://habr.com/ru/post/446662/
https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B0%D0%BD%D0%B7%D0%
B0%D0%BA%D1%86%D0%B8%D1%8F_(%D0%B8%D0%BD%D1%84%D0%BE%D1%
80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)
https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%B
C%D0%B0_CAP
Всё :)