Читайте также:
|
|
В начале параграфа «Хранимые процедуры» был приведен пример про «многоэтажные» обновления таблиц, реализующие элементарное (неделимое) с точки зрения пользователя действие. Последовательность SQL-команд, выполняющих это действие, не может быть прервана на середине – это приведет к некорректному состоянию данных.
Блок операций, которые либо должны быть выполнены все, либо не выполнена ни одна из них, называется транзакцией. Если какая-то операция по ходу транзакции не сможет выполниться или приведет к ошибке, следует отменить все изменения данных, произошедшие с начала транзакции, и вернуть базу в то состояние, которое она имела на момент начала этой транзакции. Отмена изменений называется откатом транзакции (rollback). Если все операции по ходу транзакции прошли успешно, без ошибок, то производится фиксация транзакции (commit), после чего отменить изменения уже нельзя.
При выполнении транзакций СУБД придерживается правил обработки команд, сформулированных в виде требований ACID (по начальным буквам требований):
A tomicity (Атомарность) – выполняемые в транзакции изменения будут либо выполнены все, либо не будут выполнены совсем.
C onsistency(Согласованность) – данные в базе до и после выполнения транзакции должны находиться в согласованном состоянии; внутри транзакции возможна временная несогласованность. Под согласованностью подразумевается соблюдение логического состояния данных. Например, имеются таблицы Заказы(Номер (PK), Дата, СуммаКОплате) и СодержимоеЗаказов(НомерЗаказа(FK), КодТовара (FK), Цена, Количество). Вся процедура оформления нового заказа представляет собой транзакцию: сначала добавляется новая строка в Заказы, при этом СуммаКОплате =0. Потом набираются товары – добавляется несколько строк в СодержимоеЗаказов. Последним шагом происходит расчет СуммыКОплате, исходя из содержимого заказа. В данном примере согласованность данных – это равенство СуммыКОплате = å Цена * Количество товаров, входящих в заказ. Пока добавляются товары в заказ, поле СуммаКОплате =0 – временная несогласованность данных.
I solation (Изолированность) – изменения, сделанные одной транзакцией, не должны зависеть от изменений, сделанных другой транзакцией. То есть работа каждой транзакции должна происходить так, как будто эта транзакция работает с базой данных монопольно. Она должна видеть только те изменения, которая сделала сама (а фактически в то же самое время другие транзакции могут обновлять эти же данные, но СУБД так «подтасовывает» данные в таблицах, что транзакции видят только свои изменения).
Транзакция видит данные либо в состоянии, которое было до начала работы другой транзакции, либо в состоянии после того, как работа второй транзакции была завершена. Одна транзакция не может просмотреть промежуточное состояние данных, изменяемых другой транзакцией. Это свойство транзакций называется сериализуемостью. Сериализуемость – свойство транзакций, когда в результате их параллельного выполнения результат таков, как при последовательном выполнении этих же транзакций. На практике обеспечение сериализуемости транзакций приводит к замедлению их работы (транзакции «тормозят»), поэтому, когда быстродействие системы важнее, намеренно отказываются от полной изолированности транзакций, допуская их частичную изолированность (и следовательно некоторые типы конфликтов совместного доступа).
D urability (устойчивость, долговечность) – после фиксации транзакции (commit) все сделанные изменения сохраняются в базе, и ничто не может вернуть базу в состояние, которое она имела до начала транзакции.
В лабораторной работе «элементарные» действия пользователя следует оформлять в виде транзакций. По длительности транзакции условно можно разделить на короткие (последовательность SQL-команд, выполняемых друг за другом без задержек – порядка от микросекунд до секунд) и длинные, или бизнес-транзакции [1] (связаны с ожиданием действий пользователя, как, например, добавление товаров в заказ – могут длиться минуты, часы, а могут прерваться из-за обрыва связи).
Для коротких транзакций:
в Firebird/Interbase ничего специально делать не надо – каждая хранимая процедура автоматически является транзакцией.
В Microsoft SQL Server 2000 управлять транзакциями (начинать, завершать) приходится вручную – с помощью SQL-инструкций.
BEGIN TRAN ИмяТранзакции
COMMIT TRAN ИмяТранзакции
ROLLBACK TRAN ИмяТранзакции
Здесь допускаются вложенные транзакции. Имя транзакции можно не указывать, если транзакции не вложенные, а идут последовательно друг за другом.
Грубо говоря, в теле хранимой процедуры, оформляемой как транзакция, первым оператором стоит BEGIN TRAN, последним COMMIT TRAN, или ROLLBACK TRAN, если процедура завершилась ошибкой.
Еще есть возможность – в теле транзакции объявлять «точки сохранения» и откатывать транзакцию не полностью, а до точки сохранения.
SAVE TRAN ИмяТочки
ROLLBACK TRAN ИмяТочки
К реализации длинных транзакций существует два подхода:
1) пессимистический. Заключается в том, что клиентское приложение передает на сервер SQL-команду BEGIN TRAN – и сервер будет воспринимать все дальнейшие команды от приложения в контексте текущей транзакции (со всеми вытекающими последствиями: будет блокировать таблицы, к которым обратилась ваша программа, тормозя работу других пользователей). Как только приложение посылает команду COMMIT или ROLLBACK, блокировки снимаются. То есть транзакция живет, как эгоист – сама выполняется без ошибок, но осложняет жизнь другим.
2) оптимистический. Алгоритмы бизнес-логики делаются вообще без транзакций, либо в транзакцию оборачивают самый критический участок минимальной длительности. Идея оптимистического подхода основана на предположении, что «авось», пока шла многоэтапная обработка данных, никто из других пользователей эти данные не менял. Если все-таки меняли, то «начинай алгоритм бизнес-логики сначала» – пользователю предлагается обновить данные и повторить попытку.
Пример:
Т. Полезны из-за сериализуемости. Перейти на конфликты доступа.
Многопользовательская база данных (таковой является большинство вариантов лабораторной работы) предполагает, что к одним и тем же данным могут одновременно обращаться несколько клиентских программ. Если программы одновременно читают одну и ту же строчку таблицы, конфликтов не возникает. Если же они пытаются одновременно менять ее (обновлять или удалять), результат может оказаться непредсказуемым (зависит, кто раньше успел). Это называется конфликтом совместного доступа. Конфликтными являются ситуации: чтение–запись (одно приложение меняет данные, которые сейчас читает другое приложение) и запись–запись (одновременно меняют одни и те же данные).
Чтобы
Конфликты совместного доступа.
Транзакции. Уровни изолированности. Установка уровня в СУБД.
Пример ЛР2 для примера из ЛР1.
Пример отката в триггере.
Обработка ошибок (RAISERROR, EXCEPTIONS)
Обращение к полям IDENTITY из других таблиц (свойство @@identity), создание глобальных уникальных полей (уникальных по нескольким таблицам) – см. раздел IDENTITY property\Creating and modifying identifying columns. Функция NEWID() возвращает GUID. Используется для того, чтобы при объединении таблиц, созданных в нескольких базах данных, не было конфликтов из-за повторений внешних ключей.
Таблица- образец
№ п/п | Описание действия | Входные параметры (имя, тип) | Выходные параметры (имя, тип) | Алгоритм выполнения |
Дата добавления: 2015-09-11; просмотров: 72 | Поможем написать вашу работу | Нарушение авторских прав |