ACID: всичко или нищо
Накратко: Транзакцията прави няколко заявки едно цяло, което се изпълнява изцяло или никак, а ACID са четирите ѝ обещания: атомарност, консистентност, изолация и трайност.
Проблем
Поръчката, спряла по средата
Теодора поръчва два хляба и нещо, което програмата е взела от стара количка: продукт 99, който вече го няма. Програмата прави поръчката с две заявки: първо самата поръчка, после редовете ѝ. Пусни ги:
Втората заявка спира с грешка: продукт 99 не съществува. Но първата вече е минала. В базата остава поръчка 61 без нито един ред:
Поръчка за 0 продукта. Куриерът ще получи празен плик, а отчетите ще броят една поръчка повече. Същото става, ако сървърът спре между двете заявки.
Идеята
Транзакция
Действието „направи поръчка“ е няколко заявки, които имат смисъл само заедно. Транзакцията ги прави едно цяло:
BEGIN;я започва.COMMIT;я потвърждава: всичко влиза наведнъж.ROLLBACK;я отменя: все едно нищо не е било.
Ето цялата поръчка: самата поръчка, двата ѝ реда и наличностите, в една транзакция:
Ако някоя от заявките между BEGIN и COMMIT спре, програмата казва ROLLBACK и базата се връща, както е била. Ето отказа:
Поръчките са пак 60. Поръчка 61 е била в базата само вътре в транзакцията.
Пробвай
Отмени го
Колега е започнал транзакция и е изтрил всички отзиви. Добави ред, който отменя изтриването, преди броенето.
Решение
BEGIN;
DELETE FROM reviews;
ROLLBACK;
SELECT COUNT(*) AS reviews FROM reviews;ROLLBACK; преди SELECT. Отзивите пак са 16. Ако беше COMMIT;, щяха да изчезнат завинаги.
Идеята
ACID
Базите обещават четири неща за транзакциите. По първите букви на английските думи това се казва ACID:
- Atomicity, неделимост. Всичко или нищо. Поръчка без редове не може да остане.
- Consistency, съгласуваност. След транзакцията всички правила на базата са спазени: ключове,
CHECK,UNIQUE. - Isolation, изолация. Две транзакции, които вървят едновременно, не си пречат, все едно са една след друга. Колко точно, ще видим в урока за едновременната работа.
- Durability, трайност. След
COMMITпромяната е на диска. Спирането на тока не я трие.
По-точно, за любопитните
Всяка отделна заявка вече е малка транзакция: INSERT с три реда, от които единият нарушава правило, не вкарва нито един. Затова в първото поле редът на хляба също не влезе. Проблемът започва, когато едно действие е от няколко заявки. Тогава BEGIN и COMMIT ги пише програмата.
Упражнение
Поръчката на Явор
Явор (клиент 20) поръчва 1 пакет кафе на зърна (продукт 17, 14,90 €). Направи поръчка 61 от днес (2026-10-25) със състояние new, реда ѝ и намали наличността, всичко в една транзакция.
Решение
BEGIN;
INSERT INTO orders (id, customer_id, ordered_at, status) VALUES (61, 20, '2026-10-25', 'new');
INSERT INTO order_items (order_id, product_id, quantity, unit_price) VALUES (61, 17, 1, 14.9);
UPDATE products SET stock = stock - 1 WHERE id = 17;
COMMIT;Три заявки между BEGIN; и COMMIT;: поръчката, редът, наличността. Проверката гледа поръчка 61 с реда ѝ и новата наличност на кафето: 14.
Тест
Провери се
Свързани уроци
Раздел „Свързани уроци“- Нужно отпреди: LEFT JOIN: и редовете без двойка · INSERT: нови редове · UPDATE: промяна на редове · DELETE: изтриване на редове
- Продължава в: BEGIN, COMMIT, ROLLBACK · Едновременни транзакции · Тригери · Миграции на схемата
- Задачи по темата: Транзакции