Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

2008 г.

Базы данных. Вводный курс

Сергей Кузнецов

Назад Содержание Вперёд

22.3. Управление транзакциями в SQL

Область организации транзакций и управления ими настолько широка, что заслуживает отдельных книг и учебных курсов. Несмотря на то, что в курсе имеется отдельная Лекция 13, посвященная методам управления транзакциями, в этом разделе мы независимо обсудим управление транзакциями в контексте SQL.

22.3.1. ACID-транзакция

В SQL:1999 поддерживается классическое понимание транзакции, характеризуемое аббревиатурой ACID (от Atomicy, Consistency, Isolation и Durability). В соответствии с этим понятием под транзакцией разумеется последовательность операций (например, над базой данных), обладающая следующими свойствами.

  • Атомарность (Atomicy). Это свойство означает, что результаты всех операций, успешно выполненных в пределах транзакции, должны быть отражены в состоянии базы данных, либо в состоянии базы данных не должно быть отражено действие ни одной операции (конечно, здесь речь идет об операциях, изменяющих состояние базы данных). Свойство атомарности, которое часто называют свойством «все или ничего», позволяет относиться к транзакции, как к динамически образуемой составной операции над базой данных177).
  • Согласованность (Consistency). В классическом смысле это свойство означает, что транзакция может быть успешно завершена с фиксацией результатов своих операций только в том случае, когда действия операций не нарушают целостность базы данных, т. е. удовлетворяют набору ограничений целостности, определенных для этой базы данных. В стандарте SQL:1999 это свойство расширяется тем, что во время выполнения транзакции разрешается устанавливать точки согласованности (см. ниже про точки сохранения) и явным образом проверять ограничения целостности178).
  • Изоляция (Isolation). Требуется, чтобы две одновременно выполняемые транзакции179) никоим образом не действовали одна на другую. Другими словами, результаты выполнения операций транзакции T1 не должны быть видны никакой другой транзакции T2 до тех пор, пока транзакция T1 не завершится успешным образом.
  • Долговечность (Durability). После успешного завершения транзакции все изменения, которые были внесены в состояние базы данных операциями этой транзакции, должны гарантированно сохраняться, даже в случае сбоев аппаратуры или программного обеспечения.

22.3.2. Порождение транзакций в SQL:1999

В соответствии со стандартом языка SQL:1999 транзакции180) могут образовываться явным образом с использованием оператора START TRANSACTION, либо неявно, когда выполняется оператор, для которого требуется контекст транзакции, а этого контекста не существует. Например, операторы SELECT, UPDATE или CREATE TABLE могут выполняться только в контексте транзакции, а для выполнения оператора CONNECT (см. раздел 22.4. Подключения и сессии) такой контекст не требуется, и выполнение оператора CONNECT не приводит к неявному образованию транзакции. Для завершения транзакции должен быть явно использован один из двух операторов – COMMIT (требование завершить транзакцию с фиксацией ее результатов) или ROLLBACK (требование завершить транзакцию с удалением результатов всех выполненных операций из состояния базы данных181)).

Установка характеристик транзакции

У каждой выполняемой транзакции имеются три характеристики, значения которых существенно влияют на действия системы при управлении транзакцией, – уровень изоляции (isolation level), режим доступа (access mode) и размер области диагностики. При неявном образовании транзакции эти характеристики устанавливаются по умолчанию: транзакция получает максимальный уровень изоляции от одновременно выполняемых транзакций; режим доступа, позволяющий выполнять и операции выборки, и операции обновления базы данных; и назначаемый по умолчанию размер области диагностики.

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

SET TRANSACTION mode_commalist
mode ::= isolation_level
        | access_mode
        | diagnostics_size
isolation_level ::= READ UNCOMMITED
                   | READ COMITTED
                   | REPEATABLE READ
                   | SERIALIZABLE
access_mode ::= READ ONLY
             | READ WRITE
diagnostics_size ::= DIAGNOSTIC SIZE value_specification

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

Как видно из синтаксических правил, у характеристики режим доступа может быть указано одно из двух значений – READ ONLY или READ WRITE. Если устанавливается режим READ ONLY, то в транзакции нельзя будет выполнять никакие операции, изменяющие базу данных, в том числе операции обновления таблиц и определения новых объектов базы данных. Если режим доступа явно не указывается, по умолчанию принимается характеристика READ WRITE, если только в качестве значения характеристики уровень изоляции не указывается READ UNCOMITTED (в этом случае устанавливается режим доступа READ ONLY).

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

Уровни изоляции будут подробно обсуждаться ниже, но здесь мы заметим, что если значение уровня изоляции явно не задано, то по умолчанию принимается уровень изоляции SERIALIZABLE. Кроме того, еще раз обратим внимание читателей, что одновременное задание уровня изоляции READ UNCOMITTED и режима доступа READ WRITE не допускается.

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

Явная инициация транзакции

Для явного образования транзакции поддерживается оператор START TRANSACTION, определяемый следующими синтаксическими правилами:

START TRANSACTION mode_commalist

Этот оператор очень похож на SET TRANSACTION. Единственное (хотя и очень существенное) отличие состоит в том, что выполнение оператора START TRANSACTION приводит не только к установке характеристик транзакции, но и к реальной инициации транзакции.

22.3.3. Уровни изоляции SQL-транзакции

В стандарте SQL:1999 уровни изоляции определяются на основе нескольких феноменов, которые могут возникать при выполнении транзакций183).

Феномен «грязного» чтения (dirty read)

Этому феномену подвержены транзакции, в которых допускается возможность видеть изменения объектов базы данных, производимые другими одновременно выполняемыми и еще не зафиксированными транзакциями. Простой пример феномена «грязного» чтения показан на рис. 22.4.


Рис. 22.4.  Феномен «грязного» чтения

На этом рисунке показано, что в момент времени t0 были образованы две транзакции T1 и T2. В момент времени t1 транзакция T1 успешно выполняет операцию модификации некоторого объекта базы данных O. В момент времени t2 (t2>t1) транзакция T2 читает объект O, после чего успешно завершается в момент времени t3. Транзакция же T1 завершается в момент времени t4 (t4>t3), причем в ней выполняется оператор ROLLBACK, что приводит к ликвидации в базе данных последствий изменения объекта O. В результате оказывается, что в транзакции T2 обрабатывались данные, которые реально не существуют в базе данных (отсюда и термин «грязные» данные).

В SQL феномен «грязного» чтения может наблюдаться у транзакций, выполняемых на уровне изоляции READ UNCOMMITTED. Рекомендуется использовать этот уровень изоляции только в тех транзакциях, для выполнения функций которых точные данные не обязательны (например, в транзакциях, производящих статистическую обработку).

Феномен неповторяемого чтения (unrepeatable read)

Этому феномену подвержены транзакции, читающие некоторые объекты базы данных и допускающие изменения уже прочитанных объектов другими транзакциями. Пример феномена неповторяемого чтения показан на рис. 22.5.


Рис. 22.5.  Феномен неповторяемого чтения

На этом рисунке показано, что в момент времени t0 были образованы две транзакции T1 и T2. В момент времени t1 транзакция T2 выполняет операцию чтения некоторого объекта базы данных O (например, производит выборку строки из таблицы с указанием значения первичного ключа). В момент времени t2 (t2>t1) транзакция T1 изменяет объект O (модифицирует или даже удаляет). В момент времени t3 (t3>t2) транзакция T2 повторно считывает объект O и обнаруживает, что он изменился или вовсе отсутствует. Другими словами, в транзакции T2 повторное выполнение выборки объекта базы данных O дало результат, отличный от результата первого выполнения (отсюда и происходит термин «неповторяемое чтение»).

В SQL феномен неповторяемого чтения может наблюдаться у транзакций, выполняемых на уровне изоляции READ COMMITTED (этот уровень изоляции, как показывает его название, гарантирует отсутствие феномена «грязного» чтения).

Феномен фантомов

Этому феномену подвержены транзакции, производящие выборку строк и таблиц базы данных и допускающие добавление к данным таблицам другими транзакциями строк, которые удовлетворяют условию выборки. Пример феномена фантомов показан на рис. 22.6.


Рис. 22.6.  Феномен фантомов

На этом рисунке показано, что в момент времени t0 были образованы две транзакции, T1 и T2. В момент времени t1 транзакция T2 выполняет операцию выборки строк из таблицы R по условию c. В момент времени t2 (t2>t1) транзакция T1 выполняет над таблицей R операцию обновления (вставки или модификации строк), в результате которой в таблице R появляются дополнительные строки, удовлетворяющие условию c. В момент времени t3 (t3>t2) транзакция T2 повторно выполняет операцию выборки строк из таблицы R по условию c и обнаруживает наличие в результате дополнительных фантомных строк.

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

Наконец, для транзакций, выполняемых на уровне изоляции SERIALIZABLE, невозможно и проявление феномена фантомов. Термин serializable (сериализуемый) используется по той причине, что при работе на данном уровне изоляции суммарный эффект выполнения набора транзакций {T1, T2, ... , Tn} идентичен эффекту некоторого последовательного выполнения этих транзакций. Это означает предельную изолированность транзакций. Общая картина взаимосвязи уровней изоляции и феноменов транзакций показана в таблице 22.2.
Таблица 22.2. Уровни изоляции и феномены
Уровень«Грязное» чтениеНеповторяемое чтениеФантомы
READ UNCOMMITTEDВозможноВозможноВозможны
READ COMMITTEDНевозможноВозможноВозможны
REPEATABLE READНевозможноНевозможноВозможны
SERIALIZABLEНевозможноНевозможноНевозможны

22.3.4. Завершение транзакций

Как мы отмечали в начале этого раздела, транзакции могут инициироваться как явным способом (с помощью оператора START TRANSACTION), так и неявно, при выполнении первого оператора, требующего наличия контекста транзакции. Для завершения транзакции всегда184) требуется выполнение одного из двух операторов COMMIT (фиксация транзакции) или ROLLBACK (откат транзакции), которые имеют следующий синтаксис:

COMMIT [ WORK ] [ AND [ NO ] CHAIN ]
ROLLBACK [ WORK ] [ AND [ NO ] CHAIN ]
[ TO SAVEPOINT savepoint_name ]

При желании завершить транзакцию таким образом, чтобы все произведенные ею изменения были навсегда сохранены в базе данных, следует завершать транзакцию оператором COMMIT (как видно из синтаксиса, допускается эквивалентный вид COMMIT WORK). Если требуется завершить транзакцию с аннулированием всех произведенных изменений, то нужно использовать оператор ROLLBACK (ROLLBACK WORK).

Заметим, что и операция фиксации транзакции, и операция отката являются достаточно сложными и выполняются не мгновенно. Поэтому в ходе выполнения этих операций, вообще говоря, может произойти аварийный отказ системы. Естественно (хотя в этом курсе мы не обсуждаем технические детали возможных реализаций), база данных будет восстановлена в свое последнее согласованное состояние, но ситуации прерванного выполнения операции фиксации и операции отката коренным образом различаются. Оператор COMMITсчитается безусловно выполненным только в том случае, когда сервер баз данных подтвердил это после выполнения всех действий, требуемых для фиксации транзакции. Аварийная ситуация во время выполнения операции ROLLBACK ничем не отличается от аварийной ситуации, возникшей в процессе выполнения транзакции. В этом случае (при восстановлении базы данных) прерванная транзакция считается незафиксированной (что так и есть), и все ее изменения автоматически удаляются из состояния базы данных. Поэтому окончательный результат выполнения операции фиксации транзакции, прерванной аварийным отказом системы, эквивалентен успешному выполнению операции отката транзакции185).

Синтаксис обоих операторов показывает, что в каждом из них может содержаться раздел AND [ NO ] CHAIN. Постараемся кратко пояснить смысл этого раздела (не вдаваясь в детали, поскольку стандарт SQL:1999 оставляет окончательное решение за реализацией).

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

Поэтому часто используется компромиссный вариант, при котором действия операторов COMMIT или ROLLBACK приводят не только к завершению текущей транзакции, но и к образованию новой транзакции186). Именно эту возможность поддерживает раздел AND [ NO ] CHAIN операторов COMMIT и ROLLBACK. Если такой раздел отсутствует в операторе завершения транзакции, то подразумевается наличие раздела AND NO CHAIN, и новая транзакция не образуется. Если же раздел AND CHAIN присутствует, то немедленно после завершения выполнения COMMIT или ROLLBACK текущей транзакции образуется новая транзакция, наследующая все характеристики завершенной транзакции.

Семантику раздела TO SAVEPOINT мы поясним немного позже.

22.3.5. Транзакции и ограничения целостности

Материал этого подраздела уже излагался в подразделе 16.3.3. Немедленная и откладываемая проверка ограничений лекции 16, но там это делалось в контексте определений ограничений целостности. Для полноты картины мы воспроизведем часть этого материала в контексте управления транзакциями.

Итак, любое ограничение целостности обладает атрибутом, определяющим время проверки данного ограничения. Этот атрибут может иметь значения DEFERRABLE (отложенная проверка) или NOT DEFERRABLE (немедленная проверка). Чтобы данное ограничение целостности могло когда-либо обладать свойством отложенной проверки, нужно, чтобы в определении такого ограничения присутствовали ключевые слова INITIALLY DEFERRED или INITIALLY IMMEDIATE. В любом случае, в каждый момент времени выполнения транзакции любое ограничение целостности находится в одном из двух состояний – отложенная проверка или немедленная проверка. Если начальным состоянием ограничения является INITIALLY DEFERRED, то в начале любой транзакции его текущим состоянием будет отложенная проверка. Аналогично для ограничений с начальным состоянием INITIALLY IMMEDIATE.

Любое ограничение, находящееся в состоянии немедленной проверки, всегда проверяется в конце выполнения любого оператора SQL187). Немедленно проверяются и те ограничения, которые были определены как NOT DEFERRABLE, но для которых впоследствии был установлен режим немедленной проверки. Однако если текущим состоянием ограничения является отложенная проверка, оно будет проверяться только тогда, когда перейдет в состояние немедленной проверки. Это делается неявно при выполнении оператора COMMIT или явно при выполнении оператора SET CONSTRAINTS. Этот оператор имеет следующий синтаксис:

SET CONSTRAINTS { ALL | constraint_name_commalist}
   { DEFERRED | IMMEDIATE }

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

При попытке фиксации транзакции, для которой имеются одно или несколько ограничений целостности, текущим режимом которых является отложенная проверка, система (ненадолго, поскольку транзакция скоро тем или иным способом завершится) устанавливает для всех этих ограничений режим немедленной проверки и проверяет ограничения. Если какое-либо из ограничений нарушается, то операция COMMIT трактуется как операция ROLLBACK, и пользователю (или приложению) сообщается, что возникла ошибка. Избежать этой неприятной ситуации можно явным выполнением оператора SET CONSTRAINTS ALL IMMEDIATE до фиксации транзакции, для которой имеются DEFERRABLE ограничения, текущим режимом которых является отложенная проверка.


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

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

179   Здесь мы опять сталкиваемся с терминологической трудностью, существующей уже много лет. В англоязычной терминологии имеется замечательный термин concurrent, который соответствует как реально параллельному, так и квазипараллельному выполнению транзакций (или процессов). Русский эквивалент одновременный не совсем точно соответствует смыслу оригинала, но лучшего варианта пока нет.

180   Правильнее было бы говорить SQL-транзакции, но в этом курсе мы не обсуждаем другие модели транзакций и поэтому будем использовать термин «транзакция» в смысле SQL-транзакция.

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

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

183   В действительности, этот подход был введен еще в проекте System R.

184   Правильнее было бы сказать почти всегда, поскольку в SQL предусматривается особый способ терминации транзакций, инициированных программными агентами. Но в данном курсе мы этого не касаемся.

185   Возможно, некоторым читателям эти рассуждения покажутся несколько расплывчатыми, но в действительности за ними стоит развитая техника журнализации и восстановления, применяемая во всех развитых SQL-ориентированных СУБД.

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

187   Естественно, на практике проверяются только те ограничения, которые могут быть потенциально нарушены в результате выполнения соответствующего оператора.

Назад Содержание Вперёд

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...