Транзакция– набор действийвыполняемых отдельным пользователем или прикладной программой с целью получения доступа или изменения содержимого БД. СУБД должна иметь механизм, который гарантирует выполнение либо всех операций обновления данной транзакции, либо ни одной из них.
Транзакции обеспечивают:
Целостность данных с немедленной проверкой. Например, стоимость товара не может быть отрицательной. Эту проверку лучше делать сразу при заполнении пользователем формы нового заказа.
Целостность данных с откладываемой проверкой. Например, количество товара на складе может быть меньше, чем количество товара в заказе. К моменту завершения заказа другой пользователь системы из складского отдела может увеличить количество товара на складе. Поэтому есть смысл проводить эту проверку в конце, вдруг к моменту окончания формирования заказа на складе появится нужное количество товара.
Изолированность пользователей. Например, если два продавца оформляют сделку на один товар, то может оказаться, что нужного товара на всех не хватит. Таким образом, необходимо, чтобы осуществилась сделка только одного из них.
При завершении транзакции СУБД проверяет все ограничения целостности, которые могут быть нарушены, и в случае нарушения заменяет COMMIT на ROLLBACK. Однако в некоторых системах пользователь сам может выполнить ROLLBACK в середине транзакции.
СУБД с многопользовательским режимом работы создает иллюзию, что пользователи работают изолированно друг от друга. Современные СУБД поддерживают три уровня изолированности транзакций:
Первый уровень - отсутствие потерянных изменений. Пример: Павлов заказывает мыло, количество товара на складе уменьшается, До того, как Павлов подтвердит заказ Андреев заказывает мыло, а потом отменяет заказ, в результате отменяются изменения Павлова (После отгрузки товара Павлову окажется, что на складе меньше товара, чем записано в БД). Правильное решение на этом уровне заключается в том, что до завершения транзакции 1, изменяющей объект А, никакая другая транзакция не могла изменять объект A. Отсутствие потерянных изменений является минимальным требованием к СУБД по части синхронизации параллельно выполняемых транзакций.
Второй уровень - отсутствие чтения "грязных данных". Пример: пусть Павлов заказал мыла больше, чем есть на складе. До подтверждения его заказа Андреев хочет заказать мыло и видит, что его кол-во на складе отрицательно. Правильное решение на этом уровне заключается в том, что до завершения транзакции 1, изменившей объект A, никакая другая транзакция не должна читать объект A (минимальным требованием является блокировка чтения объекта A до завершения операции его изменения в транзакции 1).
Третий уровень - отсутствие неповторяющихся чтений. Пример: пусть Павлов заказывает мыло. До подтверждения его заказа Андреев заказывает мыло и подтверждает заказ. Иванов хочет увеличить объем заказа и видит, что кол-во товара на складе изменилось. Правильное решение на данном уровне заключается в том, что до завершения транзакции 1 никакая другая транзакция не должна изменять объект A. В большинстве систем это является максимальным требованием к синхронизации транзакций, хотя, как мы увидим позже, отсутствие неповторяющихся чтений еще не гарантирует реальной изолированности пользователей.
Проблема «кортежей-фантомов» вызывает ситуации, которые также противоречат изолированности пользователей. Рассмотрим следующий сценарий. Транзакция 1 выполняет оператор A выборки кортежей отношения R с условием выборки S (т.е. выбирается часть кортежей отношения R, удовлетворяющих условию S). До завершения транзакции 1 транзакция 2 вставляет в отношение R новый кортеж r, удовлетворяющий условию S, и успешно завершается. Транзакция 1 повторно выполняет оператор A, и в результате появляется кортеж, который отсутствовал при первом выполнении оператора. Фантомы бывают и на 3 уровне изолированности. Механизм решения проблемы «кортежей-фантомов» - предикатные захваты - не реализован в большинстве СУБД. Пример – дегустация. Пользователь заказывает все товары, какие есть на складе в количестве 1, начинает просматривать список. В это время на складе появляется еще товар. При обновлении информации (подтверждении заказа), этот товар попадает в заказ, но пользователь о нем не знает.