Программирование >>  Программный интерфейс приложений 

1 ... 64 65 66 [ 67 ] 68 69 70 ... 264


Возможности, которые

не поддерживает СУБД MySQL

Этот раздел посвящен описанию возможностей, которые широко представлены во многих СУБД, но отсутствуют в СУБД MySQL. Здесь показано, какие возможности отсутствуют и как можно их эмулировать. В целом можно сказать, что эти возможности не были вкдючены в арсенал СУБД MySQL по причине того, что они отрицательно влияют на производительность системы. Некоторые из возможностей появятся в следующих версиях СУБД MySQL, если это не будет противоречить основной задаче, заключающейся в поддержке высокой производительности СУБД MySQL.

Вложенные выборки. Вложенная выборка представляет собой оператор SELECT, вложенный В другой оператор SELECT:

SELECT * FROM score

WHERE event id IN (SELECT event id FROM event WHERE type = T )

Включение возможности обработки вложенных выборок запланирована в версии 3.24. А пока запросы, которые проще написать через вложенные выборки, будут эмулироваться в виде объединений. (См. раздел Преобразование вложенных выборок в объединения в этой главе.)

Транзакции и откат (commit/rollback). Транзакцией называется набор операторов SQL, который выполняется как одна целая, не прерываемая другими клиентами, операция. Возможность отката гарантирует, что операторы должны выполняться как одно целое или не выполняться вообще (т.е., если один из операторов, входящих в транзакцию, сделает сбой, то результаты всех операторов, которые были выполнены до этой точки, будут проигнорированы).

СУБД MySQL позволяет производить автоматическую блокировку отдельных операторов SQL для исключения взаимовлияния отдельных клиентов друг на друга. (Например, два пользователя не должны иметь возможность производить запись в одну и туже таблицу одновременно.) Кроме того, можно объединять фуппы операторов в целостный функциональный блок с помощью операторов LOCK TABLES И UNLOCK TABLES. Это ПОЗВОЛИТ выполнять операции, которым контроля параллельности одного оператора уже недостаточно. Проблема, связанная с транзакциями, заключается в том, что СУБД MySQL не группирует операторы автоматически и не делает автоматический откат в случае, если один из операторов в блоке дает сбой.

Посмотрим, какую пользу можно извлечь из механизма транзакций на примере ведения дел в магазине готовой одежды. Измене-



ния в складских запасах производятся в тот момент времени, когда продавцы продают товарьг Вот пример, демонстрирующий проблему, возникающую при продаже несколькими продавцами одного и того же товара и одновременной модификации ими базы данных (предположим, что текущий остаток на складе составляет 47 рубашек).

tl Продавец № 1 продает три рубашки t2 Продавец № 1 запрашивает текущий остаток (47 рубашек);

select quantity from inventory where item = shirt

t3 Продавец № 2 продает две рубашки t4 Продавец № 2 запрашивает текущий остаток (47 рубашек):

select quantity from inventory where item = shirt

ts Продавец № 1 вычисляет свой новый остаток как 47 - 3 = 44 и записывает его:

update inventory set quantity = 44 where item = shirt

t6 Продавец № 2 вычисляет свой новый остаток как 47 - 2 = 45 и записывает его:

update inventory set quantity = 45 where item = shirt

Отлично, в результате этой последовательности событий было продано пять рубашек. Но получен остаток, равный 45 рубашкам, а не 42. Проблема заключается в том, что если остаток на складе просматривается в одном операторе, а модифицируется в другом, то мы имеем дело с транзакцией, включающей несколько операторов. Действие, выполненное во втором операторе, связано с результатом, полученным в первом операторе. Если отдельные транзакции выполняются в одно и то же время, то операторы из одной транзакции влияют на операторы из другой транзакции. Вот почему в СУБД, поддерживающих транзакции, запросы продавцов будут действовать как транзакции, и запрос продавца № 2 не сможет отработать до тех пор, пока не отработает запрос продавца № 1. В СУБД MySQL аналогичного эффекта можно добиться двумя способами.

Вариант 1. Выполнить группу операторов как одно целое. Операторы можно сфуппировать и выполнить как единое целое, объединив их операторами lock tables и unlock tables. Все нужные таблицы блокируются, производятся необходимые действия, а затем блокировка снимается. Это гарантирует, что никто не сможет работать с таблицами, пока они заблокированы. При использовании блокировки таблиц ситуация с остатком на складе будет выглядеть следующим образом.



tl Продавец № 1 продает три рубашки

t2 Продавец № 1 блокирует таблицу и запрашивает текущий остаток (47 рубашек)

LOCK TABLES inventory WRITE

SELECT quantity FROM inventory WHERE item = shirt

t3 Продавец № 2 продает две рубашки

t4 Продавец № 2 пробует заблокировать таблицу, но это не получается потому, что продавец № 1 уже заблокировал таблицу

LOCK TABLES inventory WRITE

t5 Продавец № 1 вычисляет новый остаток как 47 - 3 = 44, записывает его и разблокирует таблицу

UPDATE inventory SET quantity = 44 WHERE item = shirt UNLOCK TABLES

t6 Теперь запрос на блокировку от продавца № 2 вступает в силу, и он получает новый текущий остаток на складе (44 рубашек)

SELECT quantity FROM inventory WHERE item = shirt

t7 Продавец № 2 вычисляет новый остаток как 44 - 2 = 42, записывает его и разблокирует таблицу

UPDATE inventory SET quantity = 42 WHERE item = shirt UNLOCK TABLES

В этом случае обе транзакции не пересекаются, и остаток рубашек на складе вычисляется правильно В таблицу inventory нужно бьшо вносить изменения, поэтому используется блокировка write. Если необходимо только чтение таблиц, нужно воспользоваться блокировкой read Это даст возможность другим клиентам только считывать данные из таблицы, а не производить запись в нее.

В этом примере продавец № 2 из-за того, что транзакция короткая и выполняется быстро, возможно, и не заметит факта блокировки таблицы. Но в других случаях необходимо избегать блокировки таблиц на длительный период времени.

При работе с несколькими таблицами перед выполнением групповых запросов их все необходимо заблоютровать. Однако в случае чтения из определенной таблицы необходимо использовать блокировку read Предположим, что в таблице inventory блок запросов производит некие изменения, а в таблице customer - ограничивается операциями чтения. В этом случае таблица inventory блокируется блокировкой write, таблица customer блокируется блокировкой read:

LOCK TABLES inventory WRITE, customer READ UNLOCK TABLES



1 ... 64 65 66 [ 67 ] 68 69 70 ... 264

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика