{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ |
SERIALIZABLE }
Существующие соединения не затрагиваются. Для выполнения этого оператора нужно иметь привилегию SUPER. Применение ключевого слова SESSION устанавливает уровень изоляции по умолчанию всех будущих транзакций только для текущего сеанса.
Вы можете также установить начальный глобальный уровень изоляции для сервера mysqld, запустив его с опцией
--transaction-isolation.
Банковское приложение является классическим примером, демонстрирующим необходимость транзакций. Представьте банковскую базу данных с двумя таблицами: checking (текущие счета) и savings (сберегательные счета). Чтобы перевести 200 долларов с текущего счета Джейн на ее сберегательный счет, вам нужно сделать по меньшей мере три шага.
1.Убедиться, что остаток на ее текущем счете больше 200 долларов.
2.Вычесть 200 долларов из остатка текущего счета.
3.Добавить 200 долларов к остатку сберегательного счета.
Вся операция должна быть организована как транзакция, чтобы в случае неудачи на любом из трех этапов все выполненные ранее шаги были отменены.
Вы начинаете транзакцию командой START TRANSACTION, а затем либо сохраняете изменения командой COMMIT, либо отменяете их командой ROLLBACK. Код SQL для транзакции может выглядеть следующим образом:
START TRANSACTION;
SELECT balance FROM checking WHERE customer_id =
10233276;
UPDATE checking SET balance = balance - 200.00 WHERE
customer_id = 10233276;
UPDATE savings SET balance = balance + 200.00 WHERE
customer_id = 10233276;
COMMIT;
Но сами по себе транзакции — это еще не все. Что произойдет в случае сбоя сервера базы данных во время выполнения четвертой строки? Кто знает... Клиент, вероятно, потеряет 200 долларов. А если другой процесс вклинится между выполнением строк 3 и 4 и снимет весь остаток с текущего счета? Банк предоставит клиенту кредит 200 долларов, даже не зная об этом.
4.4. Тест ACID
Транзакций недостаточно, пока система не прошла тест ACID.
Аббревиатура ACID расшифровывается как atomicity, consistency, isolation
и durability (атомарность, согласованность, изолированность и долговечность). Это тесно связанные критерии, которым должна соответствовать правильно функционирующая система обработки транзакций.
Атомарность. Транзакция должна функционировать как единая неделимая рабочая единица таким образом, чтобы вся она была либо выполнена, либо отменена. Для атомарных транзакций не существует такого понятия, как частичное выполнение: все или ничего.
Согласованность. База данных всегда должна переходить из одного согласованного состояния в другое. В нашем примере согласованность гарантирует, что сбой между строками 3 и 4 не приведет к исчезновению с текущего счета 200 долларов. Поскольку транзакция не будет подтверждена, ни одно из изменений не отразится в базе данных.
Изолированность. Результаты транзакции обычно невидимы другим транзакциям, пока она не подтверждена. В нашем примере это гарантирует, что, если программа суммирования остатков на банковских
счетах будет запущена после третьей строки перед четвертой, она по-прежнему увидит 200 долларов на текущем счете.
Долговечность (устойчивость). После подтверждения внесенные в ходе транзакции изменения становятся постоянными. Это значит, что они должны быть записаны так, чтобы данные не потерялись при сбое системы. Долговечность, однако, является несколько расплывчатой концепцией, поскольку у нее довольно много уровней. Некоторые стратегии обеспечения долговечности дают более высокие гарантии безопасности, чем другие, и ни одна из них не является надежной на 100% (если база данных долговечна сама по себе, то каким образом резервное копирование повышает долговечность?).
Транзакции ACID гарантируют, что банк не потеряет ваши деньги. Вообще очень сложно, а то и невозможно сделать это с помощью логики приложения. Сервер базы данных, поддерживающий ACID, должен выполнить множество сложных операций, о которых вы, возможно, даже не подозреваете, чтобы обеспечить гарантии ACID.
Как и в случае увеличения детализации блокировок, оборотной стороной усиленной безопасности является увеличение объема работы сервера базы. Сервер базы данных с транзакциями ACID также требует больших мощности процессора, объема памяти и дискового пространства, чем сервер без них. Как мы уже отмечали, это тот самый случай, когда архитектура подсистем хранения данных MySQL является вашим союзником. Вы сами можете решить, требует ли приложение использования транзакций. Если они не нужны, вы можете добиться большей производительности, выбрав для некоторых типов запросов нетранзакционную подсистему хранения данных. С помощью команды LOCK TABLES можно установить нужный уровень защиты без использования транзакций. Все в ваших руках.
4.5. Механизм блокировок
СУБД должна гарантировать, что если 2 транзакции выполняются параллельно, то результаты их выполнения должны быть аналогичны тем, которые были бы при их последовательном выполнении; каждый пользователь должен чувствовать себя так, как будто он работает монопольно (концепция сериализации транзакций).
Для решения проблем при параллельной работе используется механизм блокировок: одна или набор записей блокируются на момент выполнения транзакции. Поэтому желательно делать транзакции покороче, чтобы обеспечить равномерную работу пользователей в сети.
На практике используются 2 вида блокировок:
—без взаимного доступа (монопольная, exclusive locks);
—с взаимным доступом (разделяемая, shared locks).
Транзакция, предназначенная для чтения, извлечения записи, должна накладывать s-locks на читаемые записи. Транзакция, предназначенная для изменения данных, должна накладывать х-locks на эти записи. Если этой же транзакцией до этого была наложена s-locks, то эта блокировка поменяется на х-locks. Это приводит к тому, что в первом случае, только при чтении, другие пользователи могут одновременно читать ту же запись, а при изменении данных другим пользователям запрещено видеть неподтвержденные данные, пока они не будут зафиксированы.
Блокировки, как правило, задаются неявно:
—запрос на извлечение данных (select) по умолчанию считается запросом с s-locks;
—любой запрос на обновление (insert, delete, update) по умолчанию х-locks.
Некоторые СУБД поддерживают режим сосуществования s-locks, накладываемых разными клиентами на один и тот же ресурс. Т. к. если несколько человек одновременно читают одни и те же данные, то при
отказе наложившего s-locks формально получается, что данные уже можно изменять, хотя другие пользователи продолжают чтение.
В подсистеме хранения InnoDB применяется двухфазный протокол блокировки. Она может устанавливать блокировки в любой момент транзакции, но не снимает их до выполнения команд COMMIT или ROLLBACK. Все блокировки снимаются одновременно. Ранее описанные механизмы блокировки являются неявными. InnoDB обрабатывает блокировки автоматически в соответствии с вашим уровнем изоляции.
4.6. Взаимоблокировки
Взаимоблокировка возникает тогда, когда две и более транзакции взаимно удерживают и запрашивают блокировку одних и тех же ресурсов, создавая циклическую зависимость. Такие состояния наблюдаются и в том случае, если транзакции пытаются заблокировать ресурсы в разном порядке. Они могут возникнуть, когда несколько транзакций блокируют одни и те же ресурсы. Для примера рассмотрим две транзакции, обращающиеся к таблице StockPrice:
Транзакция №1
START TRANSACTION; |
|
|
|
|
|
|
|
|
UPDATE StockPrice |
SET |
close |
= |
45.50 |
WHERE |
stock_id |
= |
4 |
and date = '2002-05-01'; |
|
|
|
|
|
|
|
|
UPDATE StockPrice |
SET |
close |
= |
19.80 |
WHERE |
stock_id |
= |
3 |
and date = '2002-05-02'; |
|
|
|
|
|
|
|
|
COMMIT; |
|
|
|
|
|
|
|
|
Транзакция №2
START TRANSACTION;
UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3 and date = '2002-05-02';
UPDATE StockPrice SET high = 47.20 WHERE stock_id = 4 and date = '2002-05-01';
COMMIT;