Бесконечные ожидания и тупики
Использование блокировок может привести к различным нежелательным эффектам, таким как бесконечные ожидания и тупики.
Пример ситуации бесконечного ожидания приведен на рисунке 36.
Tранзакция Т2 | время | Tранзакция Т1 | Tранзакция Т3 | Tранзакция Т4 |
т1 | Блокиро—вание Д | |||
Чтение Д | ||||
Попытка блокиро—вания Д – отказ | тк | |||
ожидание... | тк+1 | Разблоки—рование Д | ||
Блокиро—вание Д (раньше, чем Т2) | ||||
Чтение Д | Блокиро—вание Д – отказ | |||
ожидание… |
Рисунок 36 – Пример ситуации бесконечного ожидания
Предположим, что транзакции T1, T2, Т3, Т4 исполнения программы, содержащей следующие действия: блокирование Д; чтение Д; изменение Д; подтверждение сохранения Д; разблокирование Д. Не исключена возможность того, что транзакция Т2 будет бесконечно находиться в состоянии ожидания, тогда как некоторые другие транзакции постоянно осуществляют блокировку Д, хотя и существует неограниченное число моментов, когда Т2 имеет шансы заблокировать Д. Состояние такого рода называется бесконечным ожиданием. Подобная проблема потенциально может возникнуть в любой обстановке, предусматривающей параллельное исполнение процессов (задача продажи билетов).
Теоретиками предлагаются различные пути решения этой проблемы. Простой способ заключается в том, что система предоставления блокировок должна регистрировать все неудовлетворенные немедленно запросы и предоставлять возможность блокировки элемента Д после его разблокирования первой запросившей его транзакции из числа ожидающих. Стратегия «первый вошел – первым обслужился» устраняет бесконечное ожидание, однако она может привести к тупикам.
Пример ситуации тупика приведен на рисунке 37. Есть две транзакции: транзакция Т1, содержащая команды, работающие с элементами данных А и В: LOCK(A); LOCK (B); …; UNLOCK (A); UNLOCK (B) и транзакция Т2: LOCK(B); LOCK (A); …; UNLOCK (B); UNLOCK (A). При этом не имеет значения, для каких процессов требуются элементы данных А и В в транзакциях Т1 и Т2 (команда LOCK – заблокировать элемент данных, команда UNLOCK – разблокировать элемент данных).
Транзакция T1 | время | Транзакция T2 |
LOCK(A) | Т1 | LOCK(В) |
LOCK(В) НЕТ! | Т2 | LOCK(A) НЕТ! |
Т3 | ||
ожидание | ожидание | |
Рисунок 37 – Пример ситуации тупика
Каждая из транзакций ожидает, пока другая разблокирует требуемый для неё элемент. Ожидание будет бесконечным. Ситуация, при которой каждая из множества двух или более транзакций ожидает, когда ей будет предоставлена возможность заблокировать элемент, заблокированный в данный момент времени какой—либо иной транзакцией из рассматриваемого множества, называется тупиком.
Способы предотвращения тупиков являются объектом исследования в области теории БД. Предлагаются различные методы разрешения тупиков.
1 Выполняется линейное упорядочивание элементов по какому—либо признаку (например, последовательно перечисляются все элементы, подлежащие блокированию) и вводится системное требование на составление запросов (программ): все запросы должны выполнять блокировки в этом порядке.
2 Вводится системное требование, чтобы в каждом запросе (программе) каждой транзакции все требуемые блокировки запрашивались сразу. Это позволяет СУБД управлять транзакциями без тупиковых ситуаций.
3 Никакие системные требования не вводятся. СУБД просто следит за возникновением тупиковых ситуаций. При обнаружении тупика действие одной из транзакций останавливается, все выполненные ею изменения в БД устраняются, транзакция переводится либо в состояние ожидания, либо полностью аннулируется. При этом все данные об этой транзакции СУБД фиксирует в системных журналах для возможного последующего перезапуска.
Дата добавления: 2016-10-17; просмотров: 882;