Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие.doc
Скачиваний:
153
Добавлен:
02.05.2014
Размер:
1.63 Mб
Скачать

2.3. Организация параллельных процессов обработки дан­ных

Наглядным примером автоматизированных систем, в которых над базой данных требуется параллельно выполнять ряд процессов об­работки, явля­ются системы продажи авиа- или железнодорожных би­летов. В этих систе­мах к общей БД одновременный доступ имеют многие операторы, работающие в различных транспортных агентствах, но выполняющие одни и те же функ­ции по продаже билетов пассажи­рам. Так как оператор не только читает данные из БД (поиск сво­бодных мест на требуемые рейсы), но и вносит изменения в базу (отмечает проданные места, отмечает возвращенные би­леты), то необ­ходимо принимать специальные меры для исключения возмож­ности продажи билетов на одно и то же место нескольким пассажирам.

Если бы выполнялись только операции чтения данных из БД, и не было никаких операций записи данных, то проблемы с организацией параллель­ных процессов обработки над одними и теми же данными не существовало бы. В таком случае следует максимально стремиться к использованию па­раллелизма а работе системы, чтобы повысить ее производительность. Примером подобных систем служит любая ин­формационно-справочная систе­ма, в которой пользователям разрешен только режим чтения данных из БД и в период, когда работают поль­зователи, никаких изменений данных не производится.

Однако как только пользователи получают возможность вы­полнять операции изменения одних и тех же данных в БД, ситуация изменяется. Вернемся к системе продажи билетов. Например, три раз­личных оператора, находясь в различных транспортных агенствах го­рода, одновременно зап­росили один билет до Москвы на 1 февраля, в поезде N 351, в купейном вагоне. В этом случае будет независимо друг от друга выполнено три процесса (транзакции). Транзакция - это разовое выполнение некоторой программы (программа может быть сложной прикладной, выраженной на од­ном из языков программиро­вания, а может быть реализацией простого зап­роса, выраженного на языке запросов системы).

Независимо от того, выполняется ли несколько независимых про­гонов одной и той же программы или выполняется независимо не­сколько различ­ных программ, каждая из самостоятельных реализаций самой программы считается отдельной транзакцией. Если в период выполнения этих трех транзакций в БД не поступало от других опера­торов системы изменений (именно на этот поезд, на это число, на места в купейных вагонах), то, поскольку трижды выполняется одна и та же программа, будет получе­но три одинаковых ответа. Если места удовлетворяют пассажиров, то каж­дый оператор посылает в систему сообщение, что место продано (будет также выполнено три транзакции, но уже другой программы, которая про­с­тавляет "месту" признак, что оно продано, т.е. первая транзакция по­с­тавит признак, а две другие его повторят).

Решение этой проблемы заключается в недопущении параллель­ного ис­полнения двух и более транзакций, в которых выполняется чте­ние и изме­нение одних и тех же данных.

Блокировки. Решение задачи защиты данных при параллельном доступе заключается во введение блокировок для доступа к данным. Прежде чем прочитать некоторое данное X, транзакция T1 обязана его заблокировать: УСТАНОВИТЬ - БЛОКИРОВКУ X. Блокировка предотвращает доступ к этому данному другой транзакции Т2. Транзакция Т2 должна ждать, пока транзакция T1 не закончит работу с данным Х и не разблокирует его: СНЯТЬ -БЛОКИРОВКУ X. Если некоторая транзакция пытается бло­кировать уже бло­кированный элемент, она становится в очередь на ожидание, пока блоки­ровка с этого элемента данных не будет снята.

Для реализации механизма блокировок база разбивается струк­турно на элементы, которые можно блокировать. Выбор характера и размера эле­ментов, подлежащих блокированию, выполняется исходя из специфики решаемых системой функциональных (прикладных) задач. Выбор больших по раз­меру элементов, подле­жащих блокированию (например, отношений), снижает расходы ресур­сов по поддержанию блокировок, однако снижает также и возможно­сти параллельного исполнения процессов. Выбор малых по размеру элементов, подлежащих блокированию (например, кортежей или даже атри­бутов), увеличивает возможности системы с точки зрения парал­лельного исполнения транзакций, однако увеличивает и затраты ре­сурсов системы на поддержание блокировок.

Модели блокировок. Для блокировки могут использоваться простая модель и модель с блокировкой для чтения и записи. Рассмотрим эти модели.

Простая модель. В данной модели не вводится различие блокировок для операции чтения или операции за­писи элемента X. Установление блокировки предотвращает доступ к элементу X от дру­гих транзакций как по операции чтения, так и по операции за­писи до тех пор, пока этот элемент не будет разблокирован.

Модель с блокировками для чтения и записи. В данной модели имеется два вида доступа к элементу X: дос­туп только для чтения, доступ для чтения и записи. Соответственно различа­ют два типа команд блокировки.

1. Команда блокировки элемента Х по чтению. Транзакция, в ко­торой требуется выполнить только чтение элемента X, осуществляет его блоки­ровку по чтению. Блокировка по чтению запрещает любой другой транзак­ции выполнять запись нового значения элемента X, пока он не будет разблокирован. Блокировку элемента Х по чтению мо­гут одновременно уста­навливать несколько транзакций (т.е. допуска­ется параллельная работа по чтению данных для нескольких транзак­ций).

2. Команда блокировки элемента Х по записи. Команда блоки­ровки по записи соответствует команде блокировки в простой модели, т.е. пре­дотвращается доступ к элементу Х от других транзакций по чтению и по записи. Если некоторая транзакция установила блокировку элемента Х по записи, то никакая другая транзакция не сможет его за­блокировать ни по записи, ни по чтению. Блокировка по чтению и бло­кировка по записи сни­мается одной командой; СНЯТЬ - БЛОКИРОВКУ X. В модели допускается, что транзакция может вна­чале устанавливать блокировку элемента X по чте­нию, а затем блоки­ровку элемента X по записи.

Ожидание и тупики. При использовании механизма блокировок сталки­ваются с такими двумя нежелательными явлениями, как беско­нечные ожидания и тупиковые ситуации.

Бесконечные ожидания могут, при определенных условиях, поя­вится в любой системе с параллельным выполнением процессов. На­пример, элемент Х заблокирован выполняющейся транзакцией T1. По­ступившая в систему транзакция Т2, которой необходима работа с этим элементом, переходит в состояние ожидания. В мо­мент разблокировки элемента Х тран­закцией T1, в систему поступает транзакция Т3, которой также требуется элемент Х и перехватывает инициативу по его блокировке и т.д. В таких условиях не исключена возможность, что транзакция Т2 будет все время находится в состоянии ожидания. Чтобы избежать беско­нечного ожидания, система блокировок должна регистрировать все поступив­шие запросы и предостав­лять им возможность блокировок требуемых элементов по правилу “первый вошел - первый обслуживается”.

Для пояснения тупиковой ситуации рассмотрим алгоритм двух программ П1 и П2.

Программа П1

1 шаг - войти в программу;

2 шаг - установить блокировку А;

3 шаг - читать А;

4 шаг - установить блокировку В;

5 шаг - читать В;

5 шаг - выполнить совместную обработку А и В;

7 шаг - писать А;

8 шаг - снять блокировку с А;

9 шаг - писать В;

10 шаг - снять блокировку с В;

11 шаг - выйти из программы.

Программа П2

1 шаг - войти в программу;

2 шаг - установить блокировку В;

3 шаг - читать В;

4 шаг - установить блокировку А;

5 шаг - читать А;

5 шаг - установить блокировку С;

7 шаг - читать С;

8 шаг - выполнить совместную обработку А, В и С;

9 шаг - писать В;

10 шаг - снять блокировку с В;

11 шаг - писать А;

12 шаг - с н я т ь б л о к и р о в к у с А;

13 шаг - писать С;

14 шаг - снять блокировку с А;

15 шаг - выйти из программы.

При попытке параллельного исполнения двух транзакций Т1 - выпол­нение программы П1, а Т2 - выполнение программы П2, они забло­кируют друг друга и возникнет тупиковая ситуация. Вначале Т1 заблокирует эле­мент А, а Т2 - элемент В. Здесь никаких ослож­нений нет, элементы раз­личны и система разрешает транзакциям Т1 и Т2 выполняться параллельно. Закончив 3-й шаг, транзакции Т1 и Т2 перейдут в состояние ожидания: транзакция T1 будет ждать разблокировки элемента В, за­блокирован­ного транзакцией Т2; транзакция Т2 будет ждать раз­блокировки элемен­та А, заблокированного транзакцией Т1. Ни одна транзакция не может продолжаться из-за блокировок общих элемен­тов. Это и есть тупиковая ситуация.

Существуют следующие подходы к разрешению тупиковых ситуаций.

1.Выполняется линейное упорядочение элементов по любому принципу (например, последовательно перечислить все элементы БД, подлежащих блокированию) и вводится системное требование на составление программ, т.е. все программы должны выполнять блокировки в определенном порядке. Все транзакции будут запрашивать блокировки в соответствии с принятой, единой для всех упорядоченностью элементов, что предотвратит тупики.

2.Вводится системное требование, чтобы в каждой программе все блокировки запрашивались сразу. Каждая транзакция будет единовременно запрашивать все необходимые ей блокировки. Это позволит СУБД выполнять управление транзакциями без тупиковых ситуаций.

3. Не вводится никаких системных требований на написание программ. В этом случае СУБД следит за возникновением тупиковых ситуаций. При обнаружении тупика действие одной из транзакций аннулируется, все выполненные ею изменения в БД устраняются. Транзакция переводится в состояние ожидания, и через некоторое время выполняется ее рестарт или полностью аннулируется. Чтобы выполнить рестарт или аннулирование транзакции, СУБД фиксирует транзакцию, записывая для каждой транзакции ее идентификатор, все произведенные ею вычисления, время начала и завершения. Такая информация позволяет в случае системного сбоя выполнить также рестарт всех зафиксированных транзакций, которые не успели успешно завершиться.

Соседние файлы в предмете Базы данных