Понятие транзакции
В большинстве баз данных работа с данными организована в форме транзакций (transactions). Впервые понятие транзакции вводилось в лекции №1. Транзакция – это последовательность действий с базой данных, в которой либо все действия выполняются успешно, либо не выполняется ни одно из них, т.е. база данных остается без изменений. Такая последовательность действий называется также атомарной (atomic), так как она выполняется как единое целое.
В реляционных БД транзакции выполняются с помощью инструкций INSERT, UPDATE, DELETE языка SQL (вставка, изменение или удаление записей в таблице). Подобная операция должна осуществляться целиком, т.е., если, например, удаляется запись в таблице, то она должна быть удалена полностью, а не частично. Для пользователя или программы транзакции выполняются автоматически при исполнении каждой инструкции SQL. Это контролирует СУБД.
Но часто транзакции как процедуры работы с данными являются более сложными и многоступенчатыми. Например, пусть в базе данных банковских счетов нужно перевести средства с одного счета на другой. Для этого нужно уменьшить на нужную сумму баланс одного счета и увеличить на ту же сумму баланс другого счета. Операция «перевод суммы между счетами» является транзакцией. На языке SQL это осуществляется с помощью следующих двух инструкций:
UPDATE счета
SET баланс = баланс -100
WHERE номер_счета = 950;
UPDATE счета
SET баланс = баланс +100
WHERE номер_счета = 5200;
Если между выполнением этих двух команд произойдет сбой, то это приведет к ошибке в БД. Баланс одного счета уменьшится, а второго не увеличится. В таком случае лучше, чтобы ни один из операторов не был выполнен, и БД должна возвратиться в исходное состояние, т.е. должен произойти откат транзакции.
Поэтому необходимы специальные операторы для правильного завершения транзакций.
В языке SQL для этих целей предусмотрены два оператора:
Программа может состоять из нескольких транзакций. Для указания конца каждой транзакции используется оператор COMMIT или ROLLBACK. Программа с несколькими транзакциями должна иметь следующий вид:
Начало программы
SQL – операторы транзакции 1;
COMMIT или ROLLBACK;
SQL – операторы транзакции 2;
COMMIT или ROLLBACK;
………………………………
SQL – операторы транзакции N;
COMMIT или ROLLBACK;
Конец программы
Т.о., каждая инструкция SQL является отдельной транзакцией.
Пример процедуры:
UPDATE счета
SET баланс = баланс -100
WHERE номер_счета = 950;
UPDATE счета
SET баланс = баланс +100
WHERE номер_счета = 5200;
COMMIT;
Это означает, что первое обновление счета – не окончательное, а промежуточное. Оно не станет постоянным, т.е. изменения в записи с номером счета 950 не будут записаны на диск, пока не завершится второе обновление и не выполнится команда фиксации транзакции. Теперь если между выполнением первого и второго оператора произойдет сбой, результат первого обновления не будет записан на диск, т.к. не будет выполнен COMMIT, и БД останется в прежнем состоянии. После выполнения COMMIT результаты записываются на диск, т.е. в БД. Для отката транзакции должна использоваться инструкция ROLLBACK.
Свойства транзакций
Каждая транзакция БД должна обладать четырьмя основными свойствами:
На английском языке для названия этих четырех свойств используется аббревиатура ACID.
Сходная аббревиатура (АСИД) и на русском языке, что случается редко.
Параметры транзакции
SQL – транзакции имеет два параметра – режим и уровень изоляции. Для установки значений параметров применяется SQL - оператор:
SET TRANSACTION
Режим,
ISOLATION LEVEL уровень_изоляции;
Параметр «режим» может принимать два значения:
Уровень изоляции транзакции устанавливает, как определенная транзакция может влиять на другие транзакции.
Уровень изоляции транзакции может принимать четыре значения:
Рассмотрим более подробно смысл уровней изоляции.
Самый низкий уровень изоляции транзакций – это уровень READ INCOMMITED (неподтвержденное чтение). В этом случае на выполнение определенной транзакции могут влиять как окончательные, так и промежуточные результаты других транзакций, т.е. может возникать так называемое «грязное чтение» (dirty read). При этом изменения, внесенные в своей транзакции одним пользователем, могут быть прочитаны в другой транзакции другим пользователем, даже если в первой транзакции еще не выполнен оператор COMMIT, и изменения не записаны в БД, т.е. не являются окончательными данными. Поэтому этот уровень используется относительно редко. Но он является самым быстрым.
В режиме READ COMMITED (подтвержденное чтение или чтение подтвержденных данных) транзакциям разрешается читать только подтвержденные данные. Этот уровень изоляции устраняет «грязное» чтение. Но это не решает проблему несогласованных данных. Например, пусть в ходе первой транзакции исполняется запрос, определяющий число записей в таблице. Другая транзакция, работающая с той же таблицей, удаляет или добавляет записи. Если теперь вновь выполнится первый запрос, то он определит другое количество записей, т.е. данные окажутся несогласованными. Уровень READ COMMITED подобные противоречия не устраняет.
Проблему устранения несогласованных данных решает уровень изоляции REPEATABLE READ (повторяющееся чтение). В этом режиме строки (записи) таблицы, к которым обращается определенная транзакция для записи или чтения, блокируются и до окончания её другая транзакция не может обратиться к тем же данным (записям). Но этот уровень может приводить к так называемому фиктивному («фантомному») чтению, когда могут появиться строки – призраки, добавленные в базу другой транзакцией. (“Фантом — образ чего-либо из прошлого (человек, существо, предмет) [Википедия] ”).
Если в ходе одной транзакции исполняются два запроса на выборку, а между ними другая транзакция добавит в таблицу новую строку, эта строка станет «фантомом», т.к. она неожиданно появляется в ходе одной и той же транзакции. Это и есть суть проблемы фиктивного чтения.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.