Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

MySQL. Библиотека профессионала - Аткинсон Л

..pdf
Скачиваний:
168
Добавлен:
24.05.2014
Размер:
10.41 Mб
Скачать

Глава 9. Транзакции и параллельные вычисления

Уровни изоляции

Теоретически СУБД должна обеспечивать полную изоляцию транзакций. На прак тике же вводится несколько уровней изоляции, самый высокий из которых соответству ет полной изолированности. В MySQL выбор уровня осуществляется с помощью рукцииSETTRANSACTION,подробноописаннойвглаве13,"ИнструкцииSQL".

В стандарте языка SQL определены четыре уровня изоляции: READ UNCOMMITTED, READ COMMITTED, READ и Они перечислены в порядке от наименьшей к наивысшей изолированности и по очереди решают три основные проблемы, возникающие при использовании транзакций: появление пром ежуточных данных, появление несогласованных данных и появление строк призраков.

Промежуточные данные появляются, когда незавершенная транзакция модифи цирует строку таблицы, а другая транзакция читает эту строку. Если первая транзак ция будет отменена (произойдет откат), то окажется, что вторая транзакция получи ла данные, которые официально никогда не существовали. Такое поведение проявля ется на уровне READ UNCOMMITTED.

В режиме READ COMMITTED транзакциям разрешено читать только подтвержден ные данные. Однако это не решает проблему несогласованных данных. Предполо жим, в ходетранзакции вводится запрос, определяющий число записей в таблице. По завершении этого запроса другая транзакция, работающая с той же самой таблицей, удаляет или добавляет записи. Если теперь первая транзакция повторно выполнит свой запрос, она получит другие результаты.

Проблема несогласованных данных решается на уровне REPEATABLE READ. В этом режиме строки, к которым транзакция обращается для чтения или записи, ся. Но и здесь есть проблема: строки призраки. Транзакция может заблокировать все записи, с которыми ведется работа, но она не может помешать другой транзакции доба вить строки в ту же самую таблицу. Если в ходе транзакции вводятся два запроса на вы борку, а между ними вторая транзакция добавляет в таблицу новую строку, эта строка станет "фантомом", так как она внезапно появляется в ходе одной и той же транзакции.

Врежиме SERIALIZABLEтранзакциипринудительновыполняются одна задругой. Именно такое поведение рекомендуется в стандарте SQL. Если две транзакции попы таются обновить одну и ту же строку, одна из них будет объявлена проигравшей в ту пиковой ситуации и как следствие — отменена.

Естественно, на любом уровнениже SERIALIZABLE появляется риск нарушения целостности базы данных. Как уже поминалось выше, в некоторых ситуациях такой риск вполне допустим.

Выполнениетранзакций

По умолчанию программа MySQL работает в режиме автоматического завершения транзакций. Каждый запрос представляет собой транзакцию, которая после получе ния результатов запроса немедленно завершается. Есть два способа изменить такое поведение: можноотключить режим автозавершения с помощьюинструкции SET ли бо воспользоваться инструкцией BEGIN. В первом случае каждый последующий будет входить в неявную транзакцию. Во второмслучае инструкция BEGIN поме чает начало транзакции.

Транзакции

Транзакции применимы лишь к некоторым типам таблиц. Для стандартного типа транзакции не поддерживаются. Попытка обновить таблицу типа в рамках транзакции просто приведет к немедленному обновлению таблицы. Это изме нение уже нельзя будет отменить. Если транзакции используются довольно часто, можно изменить стандартный тип таблиц, отредактировав файл конфигурации MySQL, как описано в главе 14,"Утилиты командной строки".

Транзакция отменяется с помощью инструкции ROLLBACK. Если же необходимо принять изменения, воспользуйтесь инструкцией COMMIT. В листинге показана простая транзакция, завершающаяся откатом.

BEGIN;

Query OK, 0 rows affected (0.01 sec)

SELECT *

FROM

\name \ value \

\seed \ 12345 \

1 row in set (0.00 sec)

mysql> SELECT @seed:=Value

FROM config WHERE

\ @seed:=Value \

 

 

\

12345

\

 

 

1 row in set

(0.01 sec)

 

 

mysql> UPDATE config

 

 

 

SET Value

 

 

Query OK, 1

row affected

(0.03

sec)

Rows matched:

1

Changed:

1

0

SELECT *

FROM

\name \ value \

\seed \ 18113 \

1 row in set (0.00 sec)

ROLLBACK;

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT *

FROM config;

Глава 9. Транзакции и параллельные вычисления

В транзакциях разрешается обновлять таблицы, но только с помощью инструкций INSERT и UPDATE. Изменения схемы базы данных выполняются вне транзакций. Когда вводится инструкция, вносящая изменение в схему, текущая транзакция тут же заверша ется. К завершению транзакции приводят следующие инструкции: ALTER TABLE, BEGIN, CREATE DROP RENAME TABLE, TRUNCATE.

Блокировки

Блокировки — это механизм, применяемый в MySQL дляреализации транзакций и обеспечения одновременного доступа к данным. Помимо этого можно явно запраши вать блокирование таблиц с помощью инструкции LOCK TABLES. Есть также функция позволяющая создавать произвольные блокировки. Блокировки тают с любыми таблицами, даже теми, которые не поддерживают транзакции.

На внутреннем уровне программа MySQL блокирует таблицы целиком в случае не обходимости. Допускается также блокировать строки, столбцы и страницы (под страницей понимается произвольный блок данных, связанных с таблицей). С точки зрения производительности преимущество той или иной модели проявляется по разному. Табличное блокирование выгодно для Web приложений. Блокирование на уровне строк лучше подходит для баз данных, в которых часто происходят откаты.

Инструкция LOCK TABLES описана в главе 13, "Инструкции SQL". С ее помощью можно ставить жесткую и нежесткую блокировки на одну или несколько таблиц. Не жесткая блокировка позволяет потокам осуществлять одновременное чтение данных из таблицы. Жесткая блокировка означает монопольный доступ к таблице со стороны потока. Инструкция UNLOCK TABLES снимает табличные бло кировки.

Имитировать блокировку на уровне строк можно путем добавления к таблице спе циального столбца. Ячейки этого столбца будут иметь два состояния: заблокировано и незаблокировано. Тип столбца можно задать как лучше, ENUM (подробнее об этих типах рассказывается в главе "Типы столбцов и индексов").

В листинге 9.2 приведено описание таблицы, посредством которой ся работа водяных насосов на ферме. Насосы расположены в разных местах, и каж

дый из них можно настроить на прокачку определенного объема воды в час. Про грамма, написанная на языке С, проверяет таблицу и посылает насосам команды по беспроводной сети. Если программе требуется изменить мощность насоса, она снача ла пытается заблокировать строку, устанавливая значение столбца В лис тинге 9.3 показана инструкция, блокирующая строку с идентификатором 2.

Блокировки

CREATE TABLE pump

ID INT NOT NULL

Location INT NOT NULL,

Volume

NOT NULL,

PRIMARY

UPDATE pump

SET RowLock

WHERE ID 2;

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

Функции GET_LOCK и RELEASE_LOCK реализуют другой механизм блокирова ния. Эти блокировки не связаны с какими либо ресурсами и не контролируются самой СУБД. Поэтому их называют программными блокировками, т.е. их контроль должен осуществляться программным путем. У каждой такой блокировки есть имя, и в кон кретный момент времени поток может ставить только одну программную блокировку.

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

Рассмотрим листинг 9.4. В первой инструкции запрашивается блокировка ячейки Price строки с идентификатором 3 в таблице item. Обратите внимание на то, что имя блокировки выбрано произвольно. Суть механизма в том, что все приложения придерживаются единого правила именования блокировок. Здесь нет тех издержек, которые свойственны транзакциям, хотя преимущества, посути, те же самые.

SELECT on

UPDATE item SET WHERE

SELECT RELEASE on

Глава 9. Транзакции и параллельные вычисления

Последовательности

это специальная конструкция, доступная в некоторых реля ционных СУБД, включая Oracle. Она представляет собой счетчик, используемый для создания уникальных числовых идентификаторов. Текущее значение счетчика можно извлечь с помощью инструкции SELECT. Это происходит в атомарном режиме, т.е. га рантируется, что никакие два потока не получат два одинаковых идентификатора.

В MySQL уникальные идентификаторы строк лучше всего реализуются с помощью первичных Имитация последовательностей может потребоваться при переносе приложений в MySQL. Для этого необходимо создать таблицу, состоящую из одной ячейки. Таблица будет содержать один целочисленный столбец с единствен ным начальным числом последовательности. Работа с стями ведется посредством функции описанной в главе 12, "Встроенные функции". Будучи вызванной без аргументов, она возвращает последнее значение счетчика, установленное путем или же самой функ цией. Если вызвать функцию с аргументом, она вернетзначение аргумента.

Чтобы обновить значение счетчика последовательности, нужно вызвать функцию LAST_INSERT_IDпередавейтекущеезначениесчетчика,увеличенноенаединицу. Это обновление выполняется атомарно, т.е. другие потоки не могут ему помешать. Пример работы с последовательностями показан в листинге 9.5.

CREATE TABLE

INT

Query OK, 0 rows affected (0.00 sec)

INTO seq VALUES

Query OK, 1 row affected (0.00 sec)

UPDATE seq

 

SET nextval

 

OK, 1 row affected (0.01 sec)

 

Rows matched: 1 Changed: 1

0

 

SELECT

 

 

I

|

 

 

I

101 |

 

 

1 row in set (0.00 sec)

 

 

 

UPDATE seq

 

 

 

SET nextval

 

 

Query OK, 1 row affected

(0.00

sec)

Rows matched: 1 Changed:

1

0

mysql>

SELECT

 

 

Последовательности 117

He пытайтесь извлекать значение счетчика последовательности напрямую из таб лицы: другой поток мог изменить это значение.

СПРАВОЧНИК MYSQL

часть книги представляет собой справочник по программе MySQL. В главе 10, "Типы данных, переменные и выражения", рассматриваются поддерживаемые в MySQL типы данных, расска зывается о принципах составления выражений и об использовании пе

ременных.

В главе 11, "Типы столбцов и индексов", речь пойдет о типах столбцов и индексов таблиц. Оказывается, в столбцах таблиц могут храниться не только числа и строки, но также значения даты/времени и даже боль шие двоичные объекты.

Вглаве 12, "Встроенные описаны все функции MySQL. Эти функции могут включаться в SQL инструкции с целью манипулирования столбцами, переменными и литералами. В главе 13, "Инструкции SQL", аналогичное описание дано для SQL инструкций. В MySQL поддержива ются не только стандартные инструкции языка, но и целый ряд собст венных расширений.

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

Обычно авторы помещают справочные материалы в конец книги. Я же

вставил их в середину, поскольку надеюсь, что часть времени кни га будет лежать открытой у вас на столе или на коленях. Чаще всего чита

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

ТИПЫ ДАННЫХ, ПЕРЕМЕННЫЕ И ВЫРАЖЕНИЯ

В этой главе.

Типыданных Переменные Операторы

Имена с пробелами

ft

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

Типы данных

В MySQL используются два фундаментальных типа данных: строки и числа. Значе ния этих типов заносятся в таблицы, и на основаниитипа данных столбца определя ются правила его сравнения с другими столбцами.

Строки

Строки — это последовательности символов произвольной длины. От ключевых слов SQL они отделяются кавычками. Стандарт SQL требует испол ьзовать одинарные кавычки но в MySQL, как и в других СУБД, вполне допускаются и двойные кавыч ки В листинге 10.1показано использование строк в качестве метки столбца и в операторе сравнения

mysql> SELECT AS

User

FROM

 

WHERE Host LIKE