Транзакции онлайн урок.


Транзакция - это совокупность действий системы над данными, которые либо будут исполнены в полном объеме, либо вообще не будут исполнены в случае сбоя в системе.

Например, пусть у нас есть таблица с перечнем счетов физических лиц банка. Пусть у клиента William есть два счета:

  • счет A с остатком 200 долларов

  • счет B с остатком 325 долларов


Предположим, что William хотел бы перевести деньги (скажем 20 долларов) с одного счета на другой. В терминах работы системы это выглядит так:

  1. уменьшить значение остатка на счете A на 20 долларов

  2. увеличить значение остатка на счете B на 20 долларов


Это значит что надо написать два запроса - для пункта 1 и для пункта 2. Но, например, если после выполнения пункта 2 связь с сервером базы данных пропадет? Это значит что клиент просто потеряет 20 долларов - они будут сняты со счета А, но остаток на счету В не увеличится. Для исправления ошибки необходимо откатится назад - вернуть деньги на счет А. Для этого предназначены транзакции.

Для старта транзакции необходимо исполнить запрос

START TRANSACTION;

Далее необходимо выполнить запросы в рамках транзакции. Для окончания транзакции необходимо исполнить запрос

COMMIT;

Это значит, что все что было исполнено в рамках транзакции вступит в силу. Например:

START TRANSACTION;
UPDATE teacher SET name='Hank' WHERE id = 2;
COMMIT;
+----+------------+
| id | name |
+----+------------+
| 1 | Dr House |
| 2 | Hank |
| 3 | Dr Freeman |
+----+------------+

Попробуем внести изменения в нашу таблицу при помощи транзакции, при этом разорвав связь с сервером БД.

START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

UPDATE teacher SET name='Blah' WHERE id = 2;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0

Мы изменили строку 2 в рамках транзакции. Далее мы намеренно отключаем работу MySQL (либо в специальной панели управления (XAMPP) либо через командную строку). Пытаемся исполнить запрос:

UPDATE teacher SET name='Foo' WHERE id = 3;

Получаем ошибку:

ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)
ERROR: Can't connect to the server

Далее включаем сервер MySQL. Посмотрим, вступили ли в силу изменения:

SELECT * FROM teacher;
+----+------------+
| id | name |
+----+------------+
| 1 | Dr House |
| 2 | Hank |
| 3 | Dr Freeman |
+----+------------+

Как видим, изменения в силу не вступили, хотя мы точно писали запрос по изменения строки 2.

В этом заключается суть транзакции - или все целиком, или ничего.