|
Программирование >> Создание клиентов mysql
Параллельные запросы Параллелизм - это сложная проблема для СУБД. MySQL является многопотоковой программой, поэтому вынуждена справляться с множественными запросами на подключение. Но помимо проблемы планирования возникает еще и проблема одновременного доступа к данным. Представим себе двух менеджеров, пытающихся выяснить количество единиц одного и того же товара на складе. Первый менеджер вводит инструкцию SELECT и определяет, что на складе осталось 150 единиц. Второй менеджер получает те же самые данные. Первый менеджер оформляет покупку 30-ти единиц товара, поэтому он вводит инструкцию UPDATE, устанавливая объем складского запаса равным 120-ти единицам. А тем временем второй менеджер, ничего не подозревая, оформляет аналогичный заказ на 10 единиц и тоже вводит инструкцию UPDATE. Он думает, что уменьшает количество товара на 10 единиц, а на самом деле - увеличивает на 20. В результате в базу данных вносится недостоверная информация. Программисты решают проблему параллельного доступа с помощью блокировок. Имеется центральный системный сервис, отслеживающий блокировки ресурсов и контролирующий работу потоков. Если какой-то поток захватив ресурс, поставив на него блокировку, все остальные потоки, обращающиеся к тому же самому ресурсу, вынуждены ждать его освобождения. Это может приводить к ощутимому снижению производительности, поэтому вводятся блокировки разных уровней, позволяющие точнее определять область действия допустимых и недопустимых операций. В MySQL блокировки реализуются без прямого вмешательства со стороны пользователей. Одиночные запросы выполняются в атомарном режиме, в котором каждый запрос представляет собой отдельную транзакцию. Таким образом, описанную выше проблему несогласованного заказа можно решить, объединив несколько операций в одном запросе, например: UPDATE item SET Inventory = Inventory WHERE ID = 3 He всякую последовательность операций можно выразить в виде одного запроса. Скажем, для обновления двух таблиц необходимы два запроса. В таких случаях нужно явно указывать начало и конец каждой транзакции. Транзакции Транзакция - это совокупность одной или нескольких SQL-инструкций, имеющая начало и конец. В конце транзакции происходит либо ее отмена, либо завершение. Отмена транзакции называется откатом (rollback), так как происходит последовательная отмена всех сделанных изменений. Завершение транзакции называется фиксацией (commit). Считается, что правильная транзакцияобладает следующими свойствами: атомарностью, согласованностью, изолированностью и устойчивостью. Под атомарностью понимают принцип неделимости: все инструкции, составляющие транзакцию, тельно выполняются, иначе не выполняется ни одна из них. Никаких промежуточных состояний не существует. База данных поддерживает внутреннюю согласованность за Транзакции 111 счет шшзации транзакций. Несмотря на кажущуюся одновременность событий, результаты транзакций заносятся в базу данных последовательно. Все транзакции изолируются друг от друга, а изменения, вызываемые каждой из них, становятся доступными лишь после завершения транзакции. Свойство устойчивости означает, что при успешном завершении транзакции в базу данных вносятся постоянные, неотменяемые изменения. Устойчивая база данных способна выдержать внезапную аварию, например сбой питания, и при этом остаться согласованной. Транзакции реализуются путем ведения журнала всех изменений, вносимых в базу данных в ходе каждой транзакции. Когда происходит откат, СУБД сверяется с журналом и отменяет все изменения. По журналу легко можно восстановить согласованное состояние базы данных в случае сбоя. Ведение журнала транзакций приводит к снижению производительности, поэтому в MySQL дня таблиц стандартного типа- Му-ISAM - транзакции не поддерживаются. Это одна из причин столь высокой скорости работы программы. Транзакции появились в MySQL сравнительно недавно. Они поддерживаются для таблиц расширенных типов, таких как InnoDB, Berkeley DB и Gemini. Однако следует отметить, что во многих ситуациях транзакции не нужны, так как табличных блокировок будет более чем достаточно. В отличие от других СУБД, MySQL предоставляет пользователям право выбора: можно работать с более медленными таблицами, под-держиваюш,ими транзакции, или с более быстрыми таблицами, где транзакции недопустимы. В крупных банковских базах данных транзакции, несомненно, необходимы. В подобных системах множество параллельных потоков может соперничать за право доступа к ресурсам, а потеря данных обходится слишком дорого. С другой стороны, Web-форумы, к примеру, не требуют столь тщательного управления, поскольку стоимость потери сообщения невысока. Конечно, активность посетителей форума может сравниться с активностью клиентов небольшого банка, но ведь форумы не приносят такого дохода, поэтому приобретение дополнительного оборудования для обработки транзакций является неоправданным. В основном работа с базой данных форума сводится к вставке новых сообщений и чтению существующих. Достаточно использовать первичные ключи, являющиеся автоматическими счетчиками. Internet-магазину требуется такая же целостность базы данных, как и в банке, только интенсивность трафика заметно ниже. В этой ситуации можно воспользоваться табличными блокировками. Когда программа создает заказ, она блокирует определенное число таблиц. В результате никакой другой клиент не сможет завершить свой заказ в это же самое время. Но в случае небольшого магазина, выписывающего порядка сотни счетов в день, весьма маловероятно, чтобы два клиента сделали заказы одновременно. По мере роста активности посетителей производительность системы снижается, зато целостность остается неизменной. Таблицы, незаблокированные в ходе процедуры заказа, остаются нетронутыми. Например, незачем блокировать доступ к каталогу предлагаемых товаров. Как следствие, клиентам, помещающим товары в свои корзины, не приходится дожидаться разблокирования таблицы заказов. 112 Глава 9. Транзакции и параллельные вычисления Уровни изоляции Теоретически СУБД должна обеспечивать полную изоляцию транзакций. На практике же вводится несколько уровней изоляции, самый высокий из которых соответствует полной изолированности. В MySQL выбор уровня осуществляется с помощью инс1> рукции SETTRANSACTION,подробно описанной в главе13, ИнструкцииSQL . В стандарте языка SQL определены четыре уровня изоляции: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ и SERIALIZABLE. Они перечислены в порядке от наименьшей к наивысшей изолированности и по очереди решают три основные проблемы, возникающие при использовании транзакций: появление пром ежуточных данных, появление несогласованных данных и появление строк-призраков. Промежуточные данные появляются, когда незавершенная транзакция модифицирует строку таблицы, а другая транзакция читает эту строку. Если первая транзакция будет отменена (произойдет откат), то окажется, что вторая транзакция получила данные, которые официально никогда не существовали. Такое поведение проявляется на уровне READ UNCOMMITTED. В режиме READ COMMITTED транзакциям разрешено читать только подтвержденные данные. Однако это не решает проблему несогласованнгх даннгх. Предположим, в ходетранзакции вводится запрос, определяющий число записей в таблице. По завершении этого запроса другая транзакция, работающая с той же самой таблицей, удаляет или добавляет записи. Если теперь первая транзакция повторно выполнит свой запрос, она получит другие результаты. Проблема несогласованнгх данных решается на уровне REPEATABLE READ. В этом режиме строки, к которым транзакция обращается для чтения или записи, блокируются. Но и здесь есть проблема: строки-призраки. Транзакция может заблокировать все записи, с которыми ведется работа, но она не может помешать другой транзакции добавить строки в ту же самую таблицу. Если в ходе транзакции вводятся два запроса на выборку, а между ними вторая транзакция добавляет в таблицу новую строку, эта строка станет фантомом , так как она внезапно появляется в ходе одной и той же транзакции. В режиме SERIALIZABLEтранзакции принудительновыполняются одна задругой. Именно такое поведение рекомендуется в стандарте SQL. Если две транзакции попытаются обновить одну и ту же строку, одна из них будет объявлена проигравшей в тупиковой ситуации и как следствие - отменена. Естественно, на любом уровнениже SERIALIZABLE появляется риск нарушения целостности базы данных. Как уже поминалось выше, в некоторых ситуациях такой риск вполне допустим. Выполнение транзакций По умолчанию программа MySQL работает в режиме автоматического завершения транзакций. Каждый запрос представляет собой транзакцию, которая после получения результатов запроса немедленно завершается. Есть два способа изменить такое поведение: можно отключить режим автозавершения с помощьюинструкции SET либо воспользоваться инструкцией BEGIN. В первом случае каждый последующий запрос будет входить в неявную транзакцию. Во второмслучае инструкция BEGIN помечает начало транзакции.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |