Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
baz_dan / Главы8-12.doc
Скачиваний:
64
Добавлен:
12.03.2015
Размер:
1.67 Mб
Скачать

10.8.1. Бесконечное ожидание и тупики

    Пусть существует механизм блокировки. В примере 2 блокировка предоставляется Т2 после снятия её транзакцией Т1. Рассмотрим теперь иную ситуацию. Пусть во время пребывания Т2 в состоянии ожидания транзакция Т3 только запрашивает блокировку А, и этот запрос выполняется раньше, чем запрос Т2. Далее, в то время, когда блокировку установила транзакция Т3, её запрашивает Т4, чьё требование удовлетворяется после разблокирования А транзакцией Т3 и т.д. Очевидно, при этом не исключена возможность того, что Т2 будет бесконечно находиться в состоянии ожидания.

Т1: LOCK A; UNLOCK A;

T2: – – – – – – –  -– – – – – – –  - - - - - - - - - T3: LOCK A; UNLOCK A; T4:LOCK A; UNLOCK A; T5:. .

    Тогда как некоторые другие транзакции постоянно осуществляют блокировку А, хотя и существуют неограниченное число моментов, когда транзакция Т2 имеет шансы заблокировать А.    Состояние такого рода называют  бесконечным ожиданием. Подобная проблема потенциально может возникнуть в любой обстановке, предусматривающей параллельное исполнение процессов. Простой способ избежать бесконечного ожидания заключается в том, что система предоставления блокировок должна регулировать все неудовлетворённые немедленно запросы и предоставлять возможность блокировки элемента А после его разблокирования первый запросившей её транзакции из числа ожидающих. Эта стратегия ("первым вошёл - первым обслуживается") устраняет бесконечные ожидания.

        Более серьёзная проблема, которая возникает при параллельной обработке - это так называемые «тупики».

Пример 3. Пусть имеются две транзакции Т1 и Т2, основными действиями, которых при параллельной обработке являются следующие:

Т1: lock A; lock B; unlock A; unlock B;

T2: lock B; lock A; unlock B; unlock A;

        Здесь не имеет значения, что конкретно делают с элементами А и В эти транзакции. Пусть они начинают использоваться примерно в одно и то же время. Транзакция Т1 запрашивает блокировку А и её запрос удовлетворяется. Точно так же удовлетворяется запрос транзакции Т2 на блокировку В затем Т1 запрашивает блокировку В и вынуждает ждать, поскольку этот элемент заблокирован транзакцией Т2. Аналогично Т2 запрашивает блокировку А и должна ждать, пока Т1 разблокирует А. Таким образом ни одна транзакция не может продолжаться. Каждая из них ожидает пока другая разблокирует требуемый для неё элемент. Поэтому Т1 и Т2 будут ждать бесконечно.     Ситуация, при которой каждая из множеств S двух или более транзакций ожидает, когда ей будет предоставлена возможность заблокировать элемент, заблокированный в данный момент времени какой-либо иной транзакцией их данного множества S, называют тупиком.        Так как все транзакции находятся в состоянии ожидания, то одна из них не может разблокировать элемент, необходимый для продолжения другой транзакции из S. Поэтому ожидание для них становится бесконечным.

10.8.2. Способы предотвращения тупиков

1).    Потребовать, чтобы каждая транзакция единовременно запрашивала все нужные ей блокировки. В нашем примере система предоставила бы блокировку как А, так и В для транзакции Т1, если бы она запросила блокировку первой. После завершения Т1 обе эти блокировки могли бы быть установлены для Т2, то есть Т2 должна ждать. 2).    Ввести произвольное линейное упорядочивание элементов и потребовать, чтобы все транзакции запрашивали блокировки в этом порядке.

Пусть в нашем примере А предшествует В, тогда затребовав блокировку А перед В, Т2 обнаруживает, что А уже заблокирована Т1. Элемент В не был ещё заблокирован для Т2. поэтому для Т1 доступна блокировка В, когда она будет запрашиваться. При завершении Т1 блокировки на А и В снимаются и Т2 может продолжаться. 3).    Ничего не предпринимать для их предотвращения, а периодически проверять запросы на блокировки и выявлять, не возникло ли тупиковой ситуации. Облегчает предотвращение такой проверки алгоритм построения графа, вершины которого представляют транзакции, а дуга T1->Т2 означает, что транзакция Т2 ожидает выполнения её запроса на блокировку элемента, заблокированного в данный момент транзакцией Т2. каждый цикл указывает тупик. Если же циклов нет, не существует и тупиков. В случае обнаружения тупика следует произвести рестарт хотя бы для одной из попавших в него транзакций и её воздействие на БД должно быть аннулировано.

10.9. Расписание транзакций         Последовательное исполнение транзакции при использовании блокировок элементов замедляет процесс работы с БД, хотя и работает правильно. Т1: LOCK A; UNLOCK A; 

------------------------------------T2:LOCK A; UNLOCK A; 

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

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

Пример 1. Рассмотрим, например, следующие две транзакции, которые могут быть частью бухгалтерской операции по переводу денежных средств с одного счёта на другой. Т1: READ A; A:=A-10; WRITE A; READ B; B:=B+10; WRITE B;  T2: READ B; B:=B-20; WRITE B; READ C; C:=C+20; WRITE C;  Понятно, что любое последовательное расписание обладает свойством постоянства суммы A+B+C. Пример расписания: А+В+С  

Последовательное

Т1

Т2

Read A

A=A-10

Write A

Read B

B=B+10

Write B

Read B

B=B-20

Write B

Read C

C=C+20

Write C

Сериализуемое

Т1

Т2

Read A

Read B

A=A-10

B=B-20

Write A

Write B

Read B

Read C

B=B+10

C=C+20

Write B

Write C

Несериализуемое

Т1

Т2

Read A

A=A-10

Read B

Write A

B=B-20

Read B

Write B

B=B+10

Read C

Write B

C=C+20

Write C

        Рис.10.9. Расписания транзакций

Отметим, что в последнем случае величина  B увеличивается, а не уменьшается на 10 в силу того, что Т1 читает В прежде, чем Т2 записывает новые уменьшенные значения В. Предотвратить это сложно.        В случае, когда допускаются произвольные операции с элементами невозможно проверить, дают ли два расписания одинаковый результат при всех начальных значениях элементов. На практике делаются некоторые упрощающие предположения относительно операций, выполняемых над элементами. Удобно предположить, в частности, что одинаковые их значения можно получить только при одной и той же последовательности операций. Поэтому нельзя считать, что (А+10)-20 и (А+20)-30 продуцируют одни и те же значения. Игнорируя алгебраические свойства арифметики, мы совершаем лишь «нефатальные» ошибки. Но зато расписание никогда не рассматривается как сериализуемое, если оно не является таким («фатальная» ошибка).         Нефатальные ошибки могут исключить некоторые параллельные операции и тем самым сделать систему более медленной. Однако в отличие от фатальных ошибок, при этом никогда не могут быть получены некорректные результаты.

Соседние файлы в папке baz_dan