Проблемы, возникающие при параллельной обработке данных
Пока пользователи БД читают одновременно данные, никаких проблем не происходит. Они могут появиться при одновременном обращении нескольких пользователей к одним и тем же данным с целью их корректировки. Важным при этом становится решение задачи обеспечения целостности БД, которая может быть нарушена вследствие взаимного влияния процессов друг на друга. Рассмотрим возникающие при этом проблемы.
1 Проблема утраченного обновления. Рассмотрим ситуацию, когда параллельно выполняются два процесса обработки одних и тех же данных Д пользователем А и пользователем В, т.е. выполняются две, независимые друг от друга транзакции, реализующие обновление одних и тех же данных Д (рисунок 34).
Пользователь А | Пользователь В |
Выборка Д | момент времени т1 |
момент времени т2 Выборка Д | |
Обновление данных Д | момент времени т3 |
момент времени т4 Обновление данных Д | |
! Утраченное обновление | момент времени т5 |
Рисунок 34 – Проблема утраченного обновления
И для пользователя В, и для системы в целом, обновление, сделанное пользователем А, будет утрачено (пользователь В его не увидит и сделает своё обновление, не учитывая обновление, сделанное пользователем А). Такая ситуация называется проблемой утраченного обновления.
2 Проблема зависимости от незафиксированных обновлений. Параллельно выполняются два процесса обработки одних и тех же данных Д – рисунок 35.
Пользователь А | Пользователь В |
момент времени т1 Обновление Д | |
Выборка Д | момент времени т2 |
момент времени т3 ! Откат (возврат к пред. состоянию) |
Рисунок 35 – Проблема зависимости от незафиксированного обновления
Пользователь А, если ему разрешен просмотр этих же данных, в момент времени т2 увидит данные, которые окончательно не были зафиксированы в системе, и вполне может быть, что они ошибочные. Такая ситуация называется "зависимость от незафиксированных обновлений». Транзакция А становится зависимой от не сохраненного обновления данных Д в момент т2, т.е. в транзакции А принимают участие данные, которые больше не существуют.
3 Проблема несовместимого анализа. Параллельно выполняются два процесса обработки одних и тех же данных Д. Один пользователь создает отчет, который содержит как детальные, так и итоговые строки. Второй в это время изменяет данные, влияющие на формирование итоговых строк. Могут наблюдаться противоречия в отчете: сумма детальных строк может быть не равна итоговой цифре — целостность БД не нарушается, но документ неприемлем. Такая ситуация называется "проблемой несовместимого анализа".
Для корректной обработки параллельных транзакций без создания конфликтных ситуаций необходимо использовать некоторый метод управления параллелизмом. Методы могут быть пессимистическими (консервативными), поскольку они откладывают выполнение транзакций, способных в будущем создать конфликтную ситуацию и оптимистическими – строятся на предположениях, что конфликтная ситуация маловероятна, поэтому они допускают асинхронное выполнение транзакций в БД, а проверка на наличие конфликта откладывается на момент их завершения и фиксации данных в БД.
Блокировка данных
Блокировка – процедура, используемая для управления параллельным доступом к данным. Механизм блокировки позволяет некоторой транзакции путем захвата необходимого элемента данных (от БД, в целом, до отдельного поля конкретной записи) получить доступ к данным, отклоняя попытки получения такого же доступа со стороны других транзакций, пока она их не разблокирует. Это пессимистический метод управления параллелизмом.
Существует несколько различных вариантов этого механизма, но все они основаны на одном главном принципе: транзакция должна потребовать выполнить блокировку для чтения (разделяемую) или для записи (эксклюзивную) некоторого элемента данных, перед тем, как она сможет выполнить в БД соответствующую операцию чтения или записи.
Для реализации механизма блокировок БД разбивается структурно на элементы, которые можно блокировать. Выбор характера и размера элементов, подлежащих блокированию, выполняется исходя из специфики решаемой задачи.
Влияние размеров блокируемых элементов на показатели производительности БД представлены в таблице 29.
Таблица 29 – Влияние размеров блокируемых элементов
Элементы, подлежащие блокировке/ Показатели | Большие по размеру (таблица) | Малые по размеру (запись, поле) |
1. Накладные расходы по поддержке блокировок | снижаются | увеличиваются |
2. Возможность параллельного использования процессов | снижается | расширяются |
Размер блокируемого элемента данных может быть определен в настройках среды разработчика (например, свойство соответствующего компонента Delphi), либо с помощью команд СУБД. Существуют разные модели блокировок.
1 Простая модель. Не вводится различие блокировок для операторов чтения и записи элемента данных Д. Используются две команды: установить блокировку элемента Д; снять блокировку элемента Д. При установке блокировки элемента Д предотвращается к нему доступ от других транзакций, как для выполнения операции чтения, так и для выполнения операции записи до тех пор, пока элемент Д не будет разблокирован. Это эксклюзивная или монопольная блокировка, она, как правило, автоматически устанавливается СУБД при выполнении команд Insert, Update.
2 Модель с блокировками для чтения и записи. В данной модели определено различие между видами доступа к элементу Д: доступ только для чтения; доступ только для записи. В связи с эти различают 2 типа команд блокировки:
а) команда блокировки элемента Д по записи. Такая блокировка запрещает любой другой транзакции выполнить запись нового значения элемента Д, пока он не будет разблокирован. Допускается параллельные операции по чтению элемента Д другими транзакциями;
б) команда блокировки элемента Д по чтению и записи. Эта команда соответствует команде блокировки простой модели, т.е. предотвращает доступ к элементу Д всем другим транзакциям.
В модели с блокировками по чтению допускается ситуация, когда транзакция может вначале установить блокировку элемента Д по записи, а затем блокировку элемента Д по чтению и записи.
Все блокировки снимаются командой «снять блокировку».
Любая блокировка осуществляются по следующим правилам.
1 Любая транзакция, которой необходимо получить доступ к элементу данных, должна вначале выполнить блокировку этого элемента. Блокировка может запрашиваться для чтения или для записи (если запись, то, естественно, и чтение).
2 Если элемент ещё не заблокирован какой—либо транзакцией, то блокировка будет выполнена успешно.
3 Если элемент данных уже заблокирован, СУБД анализирует, является ли тип полученного запроса совместимым с типом уже существующего блока. Если запрашивается доступ для чтения к элементу, который заблокирован для чтения, доступ к нему будет разрешен. В противном случае транзакция будет переведена в состояние ожидания, которое будет продолжаться до тех пор, пока существующий блок не снят.
4 Транзакция продолжает удерживать блокировку элемента данных до тех пор, пока она явным образом не освободит его – либо в ходе выполнения транзакции, либо по её окончании (успешном или неуспешном). Только после того, как с элемента данных будет снята блокировка для записи, другие транзакции смогут «увидеть» результаты проведенной операции записи.
Для обеспечения нормальной работы системы необходимо помнить и выполнять некоторые правила.
1 Не захватывать данные на более длительный период, чем объективно необходимо. Например, не полагаться на автоматическое разблокирование, а управлять разблокированием.
2 Открывать БД в режиме разделения, если изменению данных предшествует иное их использование, а захват БД осуществлять позднее.
3 Стремиться к полной или временной замене каждого полного захвата БД захватом отдельных записей или групп записей.
4 Немедленно отменять все свои блокирования, если неуспешна попытка очередного блокирования и осознана бесполезность дальнейшего ожидания.
5 Исследовать вероятность тупиков и обдумывать меры их предотвращения. Это делается в кругу пользователей с участием администратора БД.
6 Отменить блокирование может только владелец. Отмена может быть неявной — новое блокирование отменяет предыдущее.
Политика блокировок может поддерживаться самой СУБД с помощью соответствующих настроек. СУБД автоматически блокирует определенные элементы данных при выполнении определенных операторов. Если разработчика не удовлетворяют блокировки по умолчанию, он может управлять ими сам с помощью команд СУБД.