Читайте также:
|
|
Если бы серверы БД работали безостановочно, если бы пользователи все_ гда позволяли программам завершать выполнение и если бы приложе_ ния всегда завершались без неустранимых ошибок, прерывающих вы_ полнение, то незачем было бы обсуждать параллельный доступ к базам данных. Однако ни на одну из перечисленных ситуаций рассчитывать нельзя. Следовательно, чтобы несколько пользователей могли осущест_ влять доступ к одним и тем же данным, необходим еще один элемент.
Этой дополнительной деталью пазла параллелизма является транзак_ ция (transaction) – механизм группировки нескольких SQL_выраже_ний, позволяющий успешно выполниться всем или ни одному из них. Если клиент пытается перевести 500 долларов со сберегательного счета на текущий, он немного расстроится, если деньги будут успешно сняты с первого счета, но не внесены на второй. Какой бы ни была причина сбоя (сервер был выключен для проведения работ по техническому об_ служиванию, истекло время ожидания запроса на блокировку страни_ цы таблицы account и др.), клиент захочет вернуть свои 500 долларов.
Чтобы защититься от ошибок такого рода, программа, обрабатываю_ щая запрос на перевод, сначала начинает транзакцию, затем выполня_ ет SQL_выражения, необходимые для перемещения денег со сберега_ тельного счета на текущий, и, если все проходит успешно, завершает транзакцию, формируя команду commit (фиксировать). Однако если происходит что_то непредвиденное, программа выдает команду rollback (откат), которая указывает серверу отменить все изменения, внесенные с момента начала транзакции. Весь процесс может выглядеть так:
START TRANSACTION;
/* Снять деньги с первого счета, обеспечив достаточный остаток */ UPDATE account SET avail_balance = avail_balance _ 500
WHERE account_id = 9988 AND avail_balance > 500;
Что такое транзакция? | |
IF <Предыдущим выражением была изменена ровно одна строка> THEN /* Внести деньги на следующий счет */
UPDATE account SET avail_balance = avail_balance + 500 WHERE account_id = 9989;
IF <Предыдущим выражением была изменена ровно одна строка> THEN /* Все получилось, сделать изменения постоянными */
COMMIT; ELSE
/* Что_то не так, отменить все изменения, сделанные в данной транзакции */ ROLLBACK;
END IF; ELSE
/* Недостаток средств на счете или при обновлении возникла ошибка */ ROLLBACK;
END IF;
Хотя предыдущий фрагмент кода может показаться похожим на один из процедурных языков программирования, предостав_ ляемых основными компаниями_производителями БД, такими как PL/SQL от Oracle или Transact SQL от Microsoft, он написан на псевдокоде и не пытается имитировать ни один конкретный язык.
Приведенный выше фрагмент кода начинается с запуска транзакции. После этого делается попытка удалить 500 долларов с текущего счета и затем добавить 500 долларов на сберегательный счет. Если все про_ ходит хорошо, транзакция фиксируется; однако если что_то не так, происходит откат транзакции, т. е. все внесенные с начала транзакции изменения отменяются.
С помощью транзакции программа гарантирует, что пятьсот долларов или останутся на сберегательном счету, или перейдут на текущий счет без какой_либо возможности краха. Независимо от того, была ли тран_ закция зафиксирована или произошел откат, все ресурсы, занятые (например, блокировка записи) во время выполнения транзакции, по завершении транзакции высвобождаются.
Конечно, если программе удается завершить оба выражения update, но сервер выключается до того, как смогут выполниться commit или roll_ back, откат транзакции произойдет, когда сервер вернется в рабочий режим. (Одна из задач, которую должен выполнить сервер перед воз_ вращением в нормальный режим работы, – найти все незавершенные транзакции, запущенные на момент выключения сервера, и выпол_ нить их откат.)
Дата добавления: 2015-08-17; просмотров: 48 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Многопользовательские базы данных | | | Запуск транзакции |