|
Программирование >> Sql: полное руководство
в данном примере, в отличие от двух предыдущих, состояние базы данных правильно отражает реальную ситуацию. В наличии осталось только 39 изделий ACI-41004, поскольку клиент заказал у Джо 100 штук. Из-за того что Мэри увидела промежуточные данные профаммы Джо, ничего особенного не произошло - заказ от Джо был успешно принят. Однако с точки зрения профаммы Мэри, база данных не была целостной в течение выполняемой ею фанзакции. В начале фанзакции некоторая строка содержала одни данные, а позднее в той же самой транзакции она содержала другие данные, поскольку внешние события нарушили целостное восприятие базы данных этой профаммой. Такая несогласованность может привести к различным пробле.мам даже в том случае, если профамма Мэри не будет обновлять базу данных, опираясь на результаты первого запроса. Например, если ее профамма накапливает итоговые суммы или собирает статистические данные, то нет гарантии, что она офажает информацию правильно. В этом примере проблема заключается в том, что программа Мэри имела доступ к результатам обновления, выполненного профаммой Джо для сфоки, которую профамма Мэри уже извлекала ранее. В стандарте SQL2 эта проблема обозначена как Р2 , или проблема нестабильных результатов выборки . Профамма Мэри не смогла дважды вьшолнить один и тот же запрос и при этом получить одинаковые результаты. Проблема строк-призраков На рис. 12.9 еще раз изображена схема работы профаммы для обработки заказов. На этот раз менеджер по продажам запустил профамму генерации отчетов, которая просматривает таблицу orders и печатает список заказов от клиентов Билла Адамса, подсчитывая их итоговую сумму. Тем временем Биллу звонит клиент и делает дополнительный заказ на $5000. Заказ добавляется в базу данных, и фанзакция завершается. Вскоре после этого профамма менеджера по продажам снова просмафивает таблицу orders, выполняя тот же запрос, что и прежде. На этот раз в таблице имеется дополнительный заказ, а итоговая сумма заказов на $5000 больше, чем в результате первого запроса. Здесь, как и в предыдущем примере, проблема заключается в несогласованности данных. Состояние базы данных соответствует реальной ситуации, и целостность данных не нарушена, но один и тот же запрос, выполненный дважды в течение одной транзакции, возвращает два различных результата. В предьЕдущем примере запрос извлекал одну сфоку и противоречивость данных была вызвана выполнением инструкции update. Выполнение инсгрукции delete МОГЛО бы вызвать ту же проблему. В примере, представленном нарис. 12.9, проблема возникла в результате выполнения инсфукции insert. В первом запросе дополнительной строки не было, и после вьшолнения второго запроса сложилось такое впечатление, что она появилась из ниоткуда, как призрак. Проблема сфок-призраков, как и проблема несогласованных данных, может привести к противоречивым и неправильным расчетам. В стандарте SQL2 эта проблема обозначена как РЗ . Программа обновления 1204
Таблица ORDERS 12:00
Программа генерации отчетов 12:00
12:10
Рис. 12.9. Проблема строк-призраков Параллельные транзакции Как видно из приведенных примеров, при обновлении базы данных в многопользовательском режиме существует возможность нарушения ее целостности. Чтобы исключить такую возможность, в SQL используется механизм транзакций. Помимо того что реляционная СУБД обязана выполнять транзакции по принципу либо все, либо ничего , она имеет и др-угое обязательство по отношению к транзакциям: В ходе выполнения транзакции пользователь видит полностью непротиворечивую базу данных. Он не должен видеть промежуточные результаты транзакций других пользователей, и даже завершение таких транзакций не должно отражаться на данных, которые пользователь видит в течение транзакции . Таким образом, в реляционной базе данных транзакции Ифают ключевую роль как при восстановлении после сбоев, так и при параллельной работе нескольких пользователей. Приведенное выше правило можно сформулировать иначе, пользуясь концепцией параллельного выполнения транзакций: Когда две транзакции, див, выполняются параллельно, СУБД гарантирует, что результаты их выполнения будут точно такими же, как и в случае, если- (а) вначале выполняется транзакция л, а затем транзакция в; или (б) вначале вьшолняется транзакция в, а затем транзакция а Данная концепция называется сериализацией транзакций. На практике это означает, что каждый пользователь может работать с базой данных так, как если бы не было других пользователей, работающих параллельно Однако тот факт, что СУБД изолирует пользователя от действий других пользователей, не означает, что о них можно забыть Совсем наоборот. Поскольку другим пользователям также требуется обновлять базу данных параллельно с вами, ваши транзакции должны быть как можно более простыми и короткими, чтобы объем работы, выполняемой всеми, был больше. Предположим, например, что вы запускаете профамму, последовательно выполняющую три больших запроса на выборку. Так как профамма не обновляет базу данных, может показаться, что нет необходимости думать о фанзакциях и не фебуется использовать инструкцию COMMIT. Однако на самом деле профамма должна выполнять эту инсфукцию после каждого запроса Почему? Вспомним, что транзакция начинается автоматически вместе с первой инсфукцией SQL в профам-ме. Без инсфукции COMMIT транзакция будет продолжаться до окончания профаммы. Кроме того, СУБД гарантирует, что данные, извлекаемые в течение транзакции, будут непротиворечивыми и не будут зависеть от фанзакции других пользователей Это означает, что если ваша профамма извлек/та из базы данных определенную строку, то ни один пользователь, кроме вас, не сможет изменить эту строку до окончания вашей транзакции. Так происходит из-за того, что позднее в этой же транзакции вы можете снова извлечь ту же строку, а СУБД должна гарантировать, что в этой сфоке будут содержаться те же данные, что и при первой выборке Поэтому по мере того как ваша профамма будет последовательно выполнять три запроса, другие пользователи не смогут изменять все большее количество данных. Мораль этого примера проста: при написании профамм для промышленных реляционных баз данных всегда необходимо думать о транзакциях. Транзакции должны быть как можно короче. Используйте инсфукцию COMMIT раньше и чаще , - это хороший совет для всех, кто работает с программным SQL. Практическая реализация Сфогой модели многопользовательских транзакций может привести к существенному замедлению работы с базами данных, насчитывающими сотни и тысячи пользователей. Кроме того, логика работы многих приложений вовсе не фебует полной изоляции пользователей, которая подразумевается описанной моделью. Например, разработчик приложения может точно знать, что профамма генерации отчетов никогда не запрашивает повторно одну и ту же сфоку таблицы в течение одной транзакции. В этом случае проблема несогласованных данных просто не может возникнуть. Или, допустим, разработчик может знать, что приложение обращается к некоторым таблицам базы данных только для выборки. Если бы иметь возможность сообщить подобного рода сведения СУБД, это позволило бы усфанить многие проблемы, связанные с производительностью при обработке фанзакции.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |