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

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

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

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

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

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

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

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

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

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

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

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

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

2008 г.

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

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

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

22.3.6. Точки сохранения

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

Частичное решение этой проблемы предоставляет механизм точек сохранения (savepoint) SQL:1999. Точка сохранения представляет собой своего рода пометку в последовательности операций транзакции, которую в дальнейшем можно использовать для частичного отката транзакции с сохранением жизнеспособности транзакции и результатов операций, выполненных в транзакции до точки сохранения. Пример использования точки сохранения показан на рис. 22.7.


Рис. 22.7.  Пример транзакции с точкой сохранения

На этом рисунке после выполнения последовательности проверенных «безопасных» операций, которые, по мнению пользователя, не могут нарушить ограничения целостности с отложенной проверкой, устанавливается точка сохранения. За этой точкой следует серия «рискованных» операций. Если по каким-то причинам (например, путем немедленной проверки отложенных ограничений) затем принимается решение о нецелесообразности фиксации результатов данных операций, то выполняется частичный откат транзакции к точке сохранения, а затем фиксируются результаты безопасных операций.

Допускается установка в одной транзакции нескольких последовательных точек сохранения. При установке каждой точки сохранения ей назначается некоторое (локальное в пределах транзакции) имя, которое в дальнейшем может использоваться в операции ROLLBACK для задания точки частичного отката транзакции (см. выше синтаксис оператора ROLLBACK). Если последовательно устанавливаются две точки сохранения SP1 и SP2 и затем выполняется операция ROLLBACK TO SAVEPOINT SP1, то восстановление производится до SP1 (через SP2), и точка сохранения SP2 «забывается»188).

Для установления точки сохранения используется оператор SAVEPOINT c очевидным синтаксисом

SAVEPOINT savepoint_name

Можно также отказаться от ранее установленной точки сохранения, удалив ее из контекста транзакции. Для этого предназначен оператор RELEASE, синтаксис которого также очевиден:

RELEASE SAVEPOINT savepoint_name

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

22.4. Подключения и сессии

Может показаться странным, что мы оставили на конец этой лекции материал, который, казалось бы, необходимо знать, чтобы иметь возможность приступить к работе с какой-либо из современных систем баз данных. Объяснение очень простое. Чем ниже уровень средств языка SQL, чем ближе эти средства соприкасаются с индивидуальными особенностями реализаций, тем менее точен и конкретен стандарт SQL. А в данном разделе речь идет о средствах, реализация которых в СУБД разных поставщиков обладает очень большой спецификой.

Сильно упрощая текущую ситуацию, можно сказать, что практически все современные продукты управления SQL-ориентированными базами данных основаны на архитектуре «клиент-сервер». Принципиальная схема клиент-серверной организации показана на рис. 22.8.


Рис. 22.8.  Клиент-серверная архитектура СУБД

Конечно, это рисунок весьма условен. Под термином пользователь здесь, конечно, понимается некоторое приложение, с которым реально работает конечный пользователь (например, в этом приложении может быть реализован монитор прямого SQL). Клиентская часть СУБД – это тот системный компонент, с которым непосредственно взаимодействует пользователь. Данный компонент скрывает специфику реальных взаимодействий с серверной частью СУБД (например, используемые сетевые протоколы, если клиентская и серверная части СУБД разнесены по разным компьютерам сети). Наконец, сервер баз данных представляет собой основную часть СУБД, где, собственно, и происходит выполнение операторов SQL и осуществляется доступ к базе данных.

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

22.4.1. Установление соединений

Начиная со стандарта SQL/92, при разработке языковых средств стала приниматься во внимание клиент-серверная организация СУБД. Если говорить более точно, стал очевиден тот факт, что во всех существующих СУБД до начала работы приложения со средствами управления базой данных требуется выполнить некоторые предварительные инициирующие действия. В частности, необходимо создать контекст, в котором будет работать система баз данных. В некоторых реализациях этот контекст создается автоматически при запуске приложения, поскольку клиентская часть СУБД компонуется к приложению. В других случаях прикладная программа связывается с СУБД за счет наличия специализированных реализационно зависимых средств подключения к СУБД. Иногда контекст формируется на основе состояния системных переменных.

Очевидно, что для выработки языковых средств, которые не противоречили бы существующим реализациям, требовался компромисс. Этот компромисс выразился в том, что в SQL:1999 допускается установление связи приложения с СУБД по умолчанию, а также обеспечиваются средства явного управления соединениями. Общий подход состоит в следующем.

  • Почти все операторы SQL (с небольшим числом исключений) могут выполняться только при наличии подключения клиентской части СУБД к серверу базы данных.
  • Если соединение с сервером установлено и приложение пытается выполнить один из операторов SQL (для выполнения которых требуется соединение), то его выполняет та СУБД, с которой установлено соединение.
  • Если приложение пытается выполнить один из операторов SQL (для выполнения которых требуется соединение), а соединение не установлено, то, прежде всего, требуется установить соединение. В SQL:1999 указывается, что такое соединение является соединением с СУБД по умолчанию. Что собой представляет это умолчание, определяется в реализации. После установления соединения упомянутый оператор SQL выполняется той СУБД, с которой установлено соединение.
  • Если первым (до установки соединения) выполняемым оператором SQL является оператор CONNECT (это одно из исключений), то соединение по умолчанию не устанавливается, а происходит обращение к запрашиваемому серверу, и соединение устанавливается именно с ним.
  • Можно выполнять оператор CONNECT для установления соединений со вторым, третьим и т. д. серверами, не разрывая ранее установленные соединения. Каждое вновь установленное соединение называется текущим соединением (current connection), а все ранее установленные соединения – отложенными соединениями (dormant connection).
  • С каждым соединением ассоциирована сессия. Сессия, ассоциированная с текущим соединением, называется текущей сессией (current session), а сессии, ассоциированные с отложенными соединениями, называются отложенными сессиями (dormant session ).189)
  • Если у приложения имеется несколько соединений, можно переключать их с помощью оператора SET CONNECTION.
  • Для поддержания установленных соединений могут расходоваться значительные системные ресурсы. Поэтому может возникнуть потребность в ликвидации соединения. Это можно сделать с помощью оператора DISCONNECT. Все соединения, не ликвидированные явно до завершения работы приложения, ликвидируются системой автоматически. Попытка ликвидировать текущее соединение, в котором выполняется транзакция, расценивается как ошибка.
  • В реализации определяется, можно ли переключать соединения во время выполнения транзакции. Однако если реализация это допускает, то, в соответствии со стандартом, все операторы, выполняемые в одной транзакции, но в разных соединениях, являются частью одной общей транзакции.

22.4.2. Операторы SQL для управления соединениями

Как отмечалось выше, в эту группу входят операторы CONNECT, SET CONNECTION и DISCONNECT.

Оператор CONNECT

Оператор определяется следующими синтаксическими правилами:

CONNECT TO connection_target
connection_target ::= SQL_server_name
                        [ AS connection_name ]
                        [ USER connection_user_name ]
                   | DEFAULT

Здесь SQL_server_name – это литерально заданная символьная строка, идентифицирующая сервер, к которому требуется подключиться. Смысл (и формат) этого имени определяется в реализации.

В необязательном разделе AS указываемое имя (connection_name) выступает в роли временного имени соединения, которое впоследствии может быть использовано в операторах SET CONNECTION и DISCONNECT. Если в операторе CONNECT раздел AS не содержится, то по умолчанию connection_name совпадает с SQL_server_name.

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

Эффект использования оператора в форме CONNECT TO DEFAULT почти не отличается от результата действия системы при отсутствии какого-либо явного требования соединения. (Напомним, что соединение по умолчанию неявно устанавливается при попытке выполнения первого оператора SQL, требующего соединения.) Однако имеется одно важное отличие. Если соединение по умолчанию устанавливается неявно, а затем вдруг прерывается из-за какой-то ошибки, то оно автоматически переустанавливается при выполнении следующего оператора SQL. Если же соединение по умолчанию устанавливается явным образом, то автоматическое повторное установление соединения после его разрыва не производится.

Оператор SET CONNECTION

Оператор определяется следующими синтаксическими правилами:

SET CONNECTION connection_object
connection_object::= { connection_name | DEFAULT }

Условием успешного выполнения операции является наличие отложенного установленного соединения с именем connection_name или отложенного установленного соединения по умолчанию. В этом случае текущее соединение становится отложенным, а указанное отложенное соединение – текущим.

Оператор DISCONNECT

Оператор имеет следующий синтаксис:

DISCONNECT { connection_object | ALL | CURRENT }

Необходимым условием для возможности ликвидации соединения является отсутствие активной транзакции в этом соединении.

Если в операторе указывается connection_object, то соответствующее имя должно соответствовать установленному (текущему или отложенному) соединению. Если указывается CURRENT, то должно существовать текущее соединение.

Если оператор применяется к текущему соединению, то это соединение ликвидируется, и ни одно соединение не является текущим. В таком случае для продолжения работы необходимо установить текущее соединение при помощи операторов CONNECT или SET CONNECTION.

Если в операторе указывается ALL, то ликвидируются все соединения, включая текущее.

22.5. Заключение

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

Как легко видеть, при распространении привилегий и ролей могут возникать произвольно сложные ориентированные графы связей между объектами базы данных, владельцами привилегий, привилегиями и ролями. Если изображать сплошными стрелками передачу привилегий, прерывистыми – передачу ролей, пунктирными – владение привилегиями, а точечными – владение ролями, то даже по отношению к одной привилегии pr для одного объекта o может появиться следующий граф связей (userID означает authID, отличный от имени роли), показанному на рис. 22.8.


Рис. 22.9.  Простейший граф идентификаторов пользователя, имен ролей, объектов и привилегий

Как мог появиться такой граф? Пользователь с authID, равным userID1 (это мы предположили для упрощения, а вообще-то это могло быть и именем роли), создает объект o, становится его владельцем и тем самым обладателем привилегии pr по отношению к этому объекту. Пользователь userID1 предоставляет полномочие pr роли role1 (с правом передачи). Затем пользователю userID1 предоставляется роль role1 (с правом передачи), и он получает право исполнять эту роль. От имени роли role1 полномочие pr передается пользователю userID2 (с правом передачи), и этот же пользователь получает право исполнять роль role1 (с правом передачи). Пользователь userID2 передает роли role2 роль role1 и полномочие pr (с правом передачи). Наконец, от имени роли role2 полномочие pr и сама роль role2 передаются пользователю userID1.

Попробуйте теперь проследить, как будет выполняться операция

REVOKE pr ON o FROM role1 CASCADED

Какие узлы и дуги останутся в графе? Задача не очень сложная, но, очевидно, нетривиальная. И такого рода задачи приходится ежедневно решать администраторам больших и динамических SQL-ориентированных баз данных.

Теперь немного поговорим об управлении транзакциями. В стандарте SQL:1999 ничего не говорится о возможной реализации различных уровней изоляции. Конечно, это правильно, поскольку спецификация языка не должна накладывать какие-либо ограничения на реализации. Но, к сожалению, при использовании SQL-ориентированной СУБД некоторые знания о реализации механизма транзакций необходимы. Например, предположим, что имеются две транзакции T1 и T2, выполняемые в режиме изоляции SERIALIZABLE. Предположим, что они должны работать по «симметричному» плану, показанному на рис. 22.9.


Рис. 22.10.  Взаимные «фантомы»

Транзакции работают в наивысшем режиме изолированности. Эффект их выполнения должен быть эквивалентен эффекту некоторого последовательного выполнения транзакций T1 и T2. Но попробуйте придумать какой-либо корректный способ одновременного выполнения этих транзакций, который привел бы к эффекту их последовательного выполнения. Другими словами, для грамотного использования механизма транзакций на уровне языка SQL необходимо знать, каким образом данный механизм реализован в используемой СУБД.

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


188   Обратите внимание, что оператор ROLLBACK TO SAVEPOINT savepoint_name, хотя и синтаксически схож с «обычным» оператором ROLLBACK, принципиально отличается по своей семантике. Откат транзакции до указанной точки сохранения не означает завершения транзакции. Видимо, из соображений здравого смысла, следовало бы ввести в язык SQL операцию ABORT TRANSACTION для аварийного завершения транзакции с ликвидацией всех последствий ее операций в базе данных и, отдельно, операцию ROLLBACK TO, в которой всегда явно указывалось бы, до какого уровня требуется откат. Кстати, заметим, что комбинация ROLLBACK AND CHAIN TO SAVEPOINT savepoint_name является недопустимой (поскольку текущая транзакция не завершается).

189   Каждому соединению соответствует одна и только одна сессия. В сообществе SQL эти термины часто используются попеременно для обозначения одного и того же. Более строгие блюстители терминологии утверждают, что термин подключение относится к сетевому пути между клиентом и сервером, а ессия – это контекст, в котором работает SQL-сервер.

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

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 Тбит/с!

Новости мира 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
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...