Динамическое формирование операторов SQL на этапе выполнения
В процессе своей работы SQL сервер принимает текст запроса и интерполирует его. Это создает возможность создания внутри блоков обработки динамического формирования текстов команд SQL и их последующей интерпретации и выполнения. Для выполнения подобной конструкции в версиях FireBird, начиная с 3.0, используется команда execute statement. Команда execute statement имеет нижеприведенный синтаксис. execute statement <argument> [<option_lst>] [into <variable_list>]
<argument> ::={<paramless_stmt> | (<paramless_stmt>) | (<stmt_with_params>) (<param_values>) <paramless_stmt> - символьный литерал или переменная, содержащая текст SQL – запроса. <stmt_with_params> - символьный литерал или переменная, содержащая текст параметризованного SQL – запроса. <stmt_with_params> ::= {<stmt_with_pos_params> | {<stmt_with_named_params>} <stmt_with_pos_params> - текст, где параметры помечаются знаком ?. При выдаче команды execute statement в списке параметров задаются имена переменных, соответствующих параметрам в порядке их появления в тексте. <stmt_with_pos_params> - текст, где параметры помечаются их именем предваряемом знаком :. При выдаче команды execute statement в списке параметров задаются имена переменных, соответствующих параметрам в порядке их появления в тексте.
Отметим, что в Oracle для поддержки динамического формирования кода используются аналогичные схемы. В Oracle можно сформировать символьную переменную, а затем дать команду на компиляцию и исполнение, хранящегося в переменной текста. Подобный подход позволяет создавать настраиваемые программы и заметно сократить объем программирования при создании близких по алгоритму программ. В то же время необходимо помнить, что создаваемый таким образом код потенциально опасен, поскольку его корректность выявляется только на этапе выполнения. Более того, при синтаксической правильности текста могут возникнуть трудно отслеживаемые ошибки, особенно при редко возникающих комбинациях в исходных данных. Синтаксис для команды немедленного исполнения execute immediate execute immediate <dynamic_string> [into <var_list>] [using <d_arg_list>] [{returning | return} into <arg_list>];
<dynamic_string> - выражение, задающее текстовую строку. <var_list> - список переменных для чтения данных, используется в случае, когда <dynamic_string> содержит текст с командой select. <var_list> ::= <var> [,<var_list>] <var> - имя переменной. <d_arg_list> - список переменных, подставляемых в исходный текст <d_arg_list> ::= [{in | out | in out}] <par> [,<d_arg_list>] <arg_list> - список аргументов для заполнения <arg_list> ::= <par> [,<arg_list>] <par> - имя переменной, представляющей параметр.
Например
… procedure aaaa(mySchema in varchar(20), aPar in varchar(20)…) as declare sqlt varchar(200); res1 varchar(200); res2 varchar(200);
… sqlt:= 'select field1, field2 from ' || mySchema || 'table1 where field3=' || aPar || ' into res1, res2'; execute immediate sqlt; -- то же самое, но с использованием параметров sqlt:= 'select field1, field2 from ' || mySchema || 'table1 where field3=:id'; execute immediate sqlt into res1, res2 using aPar;
Для реализации цикла чтения используется технология курсоров. Работа с курсором требуется выполнить следующие действия: Объявление типа курсорной переменной. Объявление курсорной переменной. Связывание курсорной переменной с командой выборки (select). Цикл чтения с проверкой на конец выборки. Закрытие курсора.
Объявление типа курсорной переменной. declare type <name_cur_type> is ref cursor [return <ret_type>]; <name_cur_type> - имя курсорного типа.
Объявление курсорной переменной. <cur_name> <name_cur_type>;
Открытие курсора (базовый синтаксис). open <cur_name> for{<select_statement> | <dynamic_string>};
Чтение записи из курсора (базовый синтаксис). fetch <cur_name> into <var_list>;
Проверка на окончание считывание данных. exit when <cur_name>%notfound;
Закрытие курсора. close <cur_name>;
Рассмотрим использование курсоров на следующем примере.
… type my_cur_type is ref cursor; … w_curs my_cur_type; sqlt varchar(200); … sqlt:= 'select field1, field2 from ' || mySchema || 'table1 where field3=' || aPar; open w_curs for sqlt; loop fetch w_curs into into res1, res2; exit when w_curs%notfound; … end loop;
Помимо рассмотренных выше средств динамического формирования запросов в Oracle имеются и другие. Их подобное рассмотрение выходит за рамки настоящего пособия. Отметим только, что приведенные средства позволяют решить большинство задач динамического построения запросов внутри процедур и функций.
Глава 8. Организация хранения метаданных 8.1. Назначение и порядок использования метаданных В InterBase описания данных, или метаданные, хранятся вместе с пользовательскими данными. Чтобы система заранее могла знать, что это за данные и как ими пользоваться, имена соответствующих таблиц заранее определены. Внешне все объекты системного характера можно легко отличить от пользовательских – они имеют стандартный префикс RDB$; следовательно, имена, создаваемые пользователем, не должны иметь такого префикса. Кроме метаданных в InterBase предусмотрено и хранение разного рода комментариев к любым создаваемым пользователем информационным объектам, что обеспечивает возможность хранения документации о базе в самой базе, а это – очень большое удобство. Если Вы хотите создать максимум неудобств для себя и, особенно, для тех, кто сопровождает базу данных, никогда не пишите соответствующих комментариев. Кроме системных таблиц в базе можно создавать и системные обзоры. Автоматически они не создаются, но можно использовать готовый SQL для создания стандартных обзоров, регламентированных стандартом SQL. При желании можно также создать и свои собственные обзоры для обеспечения более удобного доступа к описаниям данных и комментариям к ним. 8.2. Системные таблицы Системные таблицы InterBase содержат метаданные базы данных. Они создаются автоматически сервером InterBase при создании базы данных и изменяются всякий раз, когда выполняются команды, изменяющие структуру данных. Попытка вручную изменять эти данные в случае ее удачи может иметь самые пагубные последствия. Для изменения структуры данных есть специальные команды, их и следует использовать. В то же время информация, содержащаяся в этих таблицах и описывающая таблицы, их поля, домены, триггеры и многое другое, доступна для прикладного программиста на основе обычных SQL запросов и весьма полезна. Глава 9. Администрирование базы данных 9.1. Управление доступом к данным Управление доступом к данным включает, прежде всего, управление списком пользователей и правами их доступа к данным и процедурам. Отметим, что права доступа регламентируются не только для пользователей, но и для групп пользователей – «ролей» и отдельных процедур. Управление может осуществляться разными способами. Рассмотрим некоторые из них. Создание списка пользователей Рассмотрим выполнение этой работы в среде Windows. Для создания списка пользователей можно воспользоваться утилитой IbConsole. Соединяемся с конкретной базой. Выбираем пункт меню File и внутри него пункт Server Login. Вводим пароль. Если данные введены правильно, то происходит соединение с базой. Для обеспечения работы по созданию пользователей необходимо иметь права администратора базы данных. При первом соединении: пользователь – SYSDBA, пароль – masterkey. Далее выбираем пункт меню Server и внутри него пункт User Security. Добавляем нового пользователя, выбрав Add User. Указываем имя пользователя (User Name), используемое для его идентификации, и пароль. При желании можно задать дополнительные данные о пользователе: фамилию, имя. Пользователь создан. При необходимости данные пользователя можно модифицировать или удалить. Единственное, что не рекомендуется, это удаление пользователя SYSDBA. Последнее связано с необходимостью переустановки InterBase для восстановления базы поддержания секретности isc4.gdb. Создание группы пользователей – роли. create role создает роль в базе данных. create role <rolename>; <rolename> - имя роли; должно быть уникальным среди функциональных имен в базе данных Ролям, созданным командой create role, могут быть предоставлены права так же, как и пользователям. Роли, в свою очередь, можно предоставлять пользователям, которые наследуют права, предоставленные ролям. Для предоставления прав ролям и их передачи пользователям используется команда grant. Для их отмены используется команда revoke. Пользователи должны определить используемую ими роль во время соединения с базой. Во время текущей сессии роль, с которой выполнено соединение, может быть изменена командой set role. Синтаксис команды имеет вид. set role <rolename> ПРИМЕР. Следующая команда создает роль с именем "administrator". create role ‘administrator’; Удаление роли. Команда drop role drop role удаляет роли из базы данных. drop role <rolename>; <rolename> - имя существующей роли, удаляемой из базы. ПРИМЕР. drop role administrator; Задание прав. Команда grant grant устанавливает права на объекты базы данных пользователям, ролям или другим объектам базы данных. Когда объект создается, права на него имеет только его создатель, и только он может выдавать права другим пользователям или объектам. Для доступа к таблице или представлению пользователь или объект нуждается в правах на select, insert, update, delete или references, для вызова процедуры в приложении - права на execute. Все права могут быть даны опцией all. Пользователи могут получить разрешение выдавать права другим пользователям передачей прав по списку <userlist>, который задается опцией with grant option. Пользователь может выдавать другим только те права, которыми располагает сам. Права могут быть даны всем пользователям опцией public на месте списка имен пользователей. Указание опции public распространяется только на пользователей, а не на объекты базы. Права могут быть ликвидированы пользователем, выдавшим их, через команду revoke. Если права были выданы с помощью all, то и ликвидированы они могут быть только в режиме all, если права были выданы с помощью public, то и ликвидированы они могут быть только в режиме public. grant { <privileges> = {all [privileges] | <privilege_list>} <privilege_list> ::= {select | delete | insert | update [(<list_col>)] | references [(<list_col>)][, <privilege_list>]
<list_col> ::= <col> [,<list_col>] <list_object> ::= {procedure | trigger | view | public} <name>[,<list_object>] <role_granted> ::= <rolename> [,<role_granted>] <role_grantee_list> ::= [user] <username> [,<role_grantee_list>] <list_col> – список столбцов, на который выдаются права. <list_col> ::= <col> [,<list_col>] <col> - имя столбца таблицы или обзора. <tname> - Имя существующей таблицы или обзора, на которые распространяются права <object> - Имя существующего объекта базы, на который распространяются права <role_grantee_list> - Список ролей и пользователей, которым передаются права with grant option - Передает права на делегирование прав пользователям, перечисленным в списке <role_grantee_list> <rolename> - Имя существующей роли, созданной командой create role role_grantee_list - Список пользователей или ролей, которым передаются права роли. Список должен быть задан в isc4.gdb group unix_group; Имя группы в UNIX, заданной в /etc/group ПРИМЕР grant select, delete on table1 to misha with grant option; grant execute on procedure p1 to procedure p2, misha; Ликвидация прав. Команда revoke revoke ликвидирует права доступа к объектам базы данных. Ликвидировать права может только тот пользователь, кто их выдал. Одному пользователю могут быть переданы одни и те же права на объект базы данных от любого числа разных пользователей. Команда revoke влечет за собой лишение выданных ранее именно этим пользователем прав. Права, выданные всем пользователям опцией public, могут быть ликвидированы командой revoke только с опцией public. revoke [grant option for]{ Все параметры команды имеют тот же смысл, что и в команде grant. 9.2. Копирование и восстановление базы данных Регулярное выполнение операций копирования базы предназначено, прежде всего, для обеспечения возможности восстановления данных после сбоев. Учитывая, что база данных InterBase физически организована в виде одного файла (при наличии файлов тени – нескольких файлов), проблем с копированием базы нет. Единственно, о чем следует помнить, так это о том, что при проведении копирования внешними программами все пользователи должны быть отключены от базы. Простое копирование, несмотря на его быстроту и надежность, хотя и допустимо, но все же не может быть рекомендовано как основной метод. Предпочтительнее создавать копию, используя средства базы данных. В этом случае одновременно с копированием выполняется и сервисное обслуживание базы данных. Использование резервной копии InterBase и особенности восстановления утилитой gbak или IBConsole дают ряд преимуществ. При резервном копировании и восстановлении помимо собственно копирования выполняется также ряд дополнительных действий, а именно: • Выполняется сборка «мусора» (удаляются устаревшие версии записей) и чистка таблицы транзакций от транзакций, завершенных откатом (rollback). • Балансируются индексы. • Освобождается пространство, занимаемое удаленными записями, и упаковываются оставшиеся данные. Это позволяет несколько уменьшить размер базы данных и ускорить работу с данными. Выполнение функции резервного копирования не требует монопольного режима. Во время выполнения копирования пользователи могут продолжать работу. При этом надо, конечно, помнить, что все данные, внесенные пользователями после начала копирования, в саму копию уже не попадут, но согласованность данных копии гарантируется. Полученная архивная копия может быть сохранена на любом устройстве. С архивной копии можно восстановить существующую или создать новую базу. При копировании, восстановлении можно выполнить также ряд действий по изменению характеристик базы (размер страницы и ряд других). В результате копирования средствами InterBase получается платформно-независимый, устойчивый снимок базы. Благодаря этому данные могут быть переданы в другую операционную систему. Это важно, поскольку различные платформы имеют аппаратно-зависимые форматы файла базы данных и поэтому базы данных не могут быть просто скопированы для переноса на другую платформу. Создание переносимых резервных копий особенно полезно в гетерогенных средах. Глава 10. Транзакции. Механизм транзакций 10.1. Понятие транзакции. Назначение транзакций Прежде всего, определимся с понятием транзакции (transaction). При внесении изменений в базу данных возникает ряд проблем, даже если с базой работает только один пользователь. Данные одного документа могут в базе храниться в различных таблицах, кроме того, они могут использовать другие данные, логически связанные с ними. Если обработка документа будет по тем или иным причинам прервана, то это может привести не только к неполноте данных, но и к нарушению их логической целостности. Например, агрегированные данные могут разойтись с исходными данными, на основе которых они были получены. При обработке множества строк таблицы возможна ситуация, когда часть строк обработана, а другая нет, например изменение размера пенсий для определенной группы. Простой повтор таких операций невозможен, поскольку неизвестно в какие именно строки были внесены изменения, а какие изменены не были. Другими словами неполный ввод (модификация или удаление) логически связанных групп данных чреват большими трудностями по восстановлению целостности и непротиворечивости информации. Для решения этой проблемы и предусматривается использования механизмов управления транзакциями. Транзакция – это группа операций с базой данных, выполняемых как единое целое. Запись данных в базу производится только при успешном выполнении всех операций группы. Если хотя бы одна из операций группы завершается неуспешно, то база данных возвращается к тому состоянию, в котором она была до выполнения первой операции группы (производится откат всех изменений). Таким образом, после устранения причины неудачного выполнения групповой операции с базой ее можно просто повторить. То есть механизм транзакций позволяет обеспечить логическую целостность данных в базе. Другими словами, транзакции – это логические единицы работы, после выполнения которых, база данных остается в целостном состоянии. Транзакции также являются единицами восстановления данных после сбоев – восстанавливаясь, система ликвидирует следы транзакций, не успевших успешно завершиться в результате программного или аппаратного сбоя. Эти два свойства транзакций определяют атомарность (неделимость) транзакции. Транзакции и поддержание логической Логическая целостность базы включает два уровня: формальную целостность и семантическую (смысловую) целостность. Под формальной логической целостностью понимается соблюдение явно описанных в базе ограничений логической целостности, таких как: • ограничения первичных ключей (primary key); • ограничения уникальных ключей (unique key); • ограничения внешних ключей (foreign key); • ограничения, задаваемые конструкциями check; • ограничения, задаваемые используемыми триггерами. Обеспечение целостности на этом уровне осуществляется стандартными средствами базы. Пользователю просто не удастся ввести данные, нарушающие эти ограничения. Под семантической логической целостностью будем понимать соблюдение требования полноты внесения группы логически связанных изменений, обеспечивающих согласованность данных в базе. Выполнение именно этого требования и реализуется с помощью механизма транзакций. Проблемы доступа к данным Механизм транзакций в однопользовательских системах покоится на трех китах: атомарность – транзакция выполняется как единое целое, согласованность – в результате выполнения транзакции база данных переходит из одного согласованного состояния в другое, долговечность – результаты транзакции сохраняются в базе данных. Если система работает только с одним пользователем, то использование транзакций гарантирует логическую целостность данных, проблем же совместного доступа здесь просто нет. Если же с системой работает несколько пользователей, то картина существенно меняется. При наличии нескольких пользователей в системе может одновременно существовать несколько транзакций, а раз так, то они могут обращаться к одним и тем же данным. Транзакции, пересекающиеся по времени и обращающиеся к одним и тем же данным называются конкурирующими. Следовательно, необходимо позаботиться о том, чтобы одна транзакция не могла менять данные, уже измененные другой транзакцией, пока та не завершилась. Поэтому перечисленных трех китов в многопользовательской системе недостаточно. К ним необходимо добавить еще черепаху или, если вам так больше нравится, четвертого кита – изолированность. Изолированность транзакций предполагает, что каждая из транзакций должна выполняться так, как если бы она была единственной. Полная изоляция транзакций может быть легко обеспечена запретом запуска следующей транзакции, пока не завершена предыдущая. Такое решение, однако, крайне неэффективно, поэтому в реальных системах требования к изоляции транзакций снижаются. Рассмотрим сначала возможные конфликты доступа к данным: • W–W (Запись–Запись). Первая транзакция изменила объект и не закончилась. Вторая транзакция пытается изменить этот объект. Результат – потеря обновления. При этом может быть нарушена согласованность хранимых данных. Допускать подобное обновление явно нельзя. Данные, измененные какой-либо транзакцией, должны быть защищены от любых изменений до ее завершения. • R–W (Чтение–Запись). Первая транзакция прочитала объект и не закончилась. Вторая транзакция пытается изменить этот объект. Результат – данные, полученные первой транзакцией, не соответствуют хранимым в базе. При повторном чтении они могут оказаться другими. Расчеты, сделанные на их основе, могут оказаться неверными. Сами данные в базе при этом остаются согласованными. • W–R (Запись–Чтение). Первая транзакция изменила объект и не закончилась. Вторая транзакция пытается прочитать этот объект. Результат – чтение неподтвержденных данных. В случае отката первой транзакции, это означает, что были прочитаны данные, которых в базе вообще никогда не было. Конфликты типа R–R (Чтение–Чтение) возникнуть не могут, поскольку данные при чтении не меняются. В связи с тем, что конфликты между транзакциями неизбежны, а полная их изоляция по соображениям эффективности невозможна, при задании транзакций предлагаются различные компромиссные варианты ограничения доступа к данным, называемые уровнями изолированности, или уровнями изоляции. Уровень изоляции определяет, как транзакция взаимодействует с другими, конкурирующими транзакциями. Отметим, что в случае успешности всех операций транзакции изменения фиксируются (commit, committed) в базе, в противном случае они отменяются (rollback, rolled back) и база "откатывается" к состоянию, в котором она была перед началом транзакции. Стандартом ANSI SQL-92 предусматривается 4 стандартных уровня изолированности транзакций: • Dirty Read – "грязное" (или "незафиксированное") чтение. Транзакция может читать не подтвержденные изменения, сделанные в других транзакциях. Например, если транзакции A и B стартовали, и поменяли записи, то они обе видят изменения друг друга. InterBase не поддерживает уровень изоляции транзакций Dirty Read. • Read Committed – невоспроизводимое (или неповторяемое) чтение. Транзакция может читать только те изменения, которые были подтверждены другими транзакциями. Например, если транзакции A и B стартовали и поменяли записи, то они не видят изменения друг друга. Транзакция А увидит изменения транзакции B только тогда, когда транзакция B завершится по commit. Повторное чтение данных транзакцией A при этом приведет к тому, что она увидит, вообще говоря, уже другие данные. InterBase полностью поддерживает уровень изоляции транзакций Read Committed. • Repeatable Read – воспроизводимое (или повторяемое) чтение. Транзакция видит только те данные, которые существовали на момент ее старта. При повторном чтении будут видны те же самые данные, хотя они могли за это время и измениться. Уровень изоляции Repeatable Read в чистом виде не поддерживается InterBase. Вместо него InterBase поддерживает уровень SNAPSHOT (снимок), который хотя и близок к Repeatable Read, но несколько "сильнее". Последнее связано с тем, что InterBase использует "версии" данных, а не их блокировку, действительно гарантируя повторное считывание тех же самых данных. Serialized – сериализуемость. Транзакция выполняются так, как будто никаких других транзакций в этот момент не существует. Или, другими словами, транзакции выполняются так, как будто они выполняются последовательно. Каждый из уровней изоляции имеет свои достоинства и недостатки. Dirty Read позволяет оперативно отслеживать все изменения в базе, но это всегда "предварительные результаты" и надо быть готовым к их отмене. Кроме того, при просмотре данных из нескольких таблиц нельзя быть уверенным в согласованности данных (логическая целостность обеспечивается только по завершении транзакции). Следующий уровень изоляции Read Committed гарантирует согласованность всех данных, но не может гарантировать их актуальности, данные могли быть уже изменены, но соответствующая операция еще не была подтверждена (Committed). Для получения обновленных данных необходимо выполнять операции повторного чтения. Неповторяемость в общем случае результатов чтения может рассматриваться и как достоинство и как недостаток. Кроме того, при сложной выборке возможно получение и просто неверных данных. Рассмотрим это на примере. Имеется две транзакции. Первая подсчитывает запас продукции на складах. Поскольку в рамках данной транзакции не производится изменений данных, то она не блокирует работу других транзакций. Вторая реализует перемещение продукции между складами и вносит соответствующие изменения в данные. Рассмотрим действие транзакций во времени. Первая транзакция прочла данные о запасе товара на складе А, после этого вторая транзакция стартовала, переместила товар со склада А на В и закончила работу (Committed). Далее первая транзакция читает данные о запасе товара на складе В. Полученные суммарные сведения о товаре на этих складах будут отличаться от реальных на объем перемещения, сделанный второй транзакцией. При этом все данные и на момент старта и на момент окончания транзакции правильны, дело в том, что считанные данные относятся к разным моментам времени. Уровень изоляции Repeatable Read жестко связан с состоянием базы на момент своего старта. Это обеспечивает возможность почти всегда при повторном чтении видеть те же самые данные. В системах с блокировкой данных это достигается запретом изменения данных, прочитанных транзакцией. В то же время такая блокировка не гарантирует от появления "фантомных данных". Пусть первая транзакция читает из таблицы данные, удовлетворяющие некоторому условию p. Другая транзакция после этого уже не может менять данные, удовлетворяющие условию p, однако, она может работать с другими данными. В результате она вносит в свои данные изменения, после которых они уже удовлетворят условию p. Транзакция, внесшая изменения, успешно завершается, изменения сохранены в базе. После этого первая транзакция вновь читает свои данные и ожидает, что они будут теми же. Но не тут-то было. В результате запроса она получит и «добавок» в виде данных, внесенных второй транзакцией. В системах с хранением версий данных, к которым относится InterBase, такого рода фантомов не будет, но и уровень изоляции называется иначе – SNAPSHOT (снимок). Данный уровень гарантирует полную согласованность всех полученных данных, но не может гарантировать их "свежести". Часть данных может оказаться устаревшей, все данные были актуальными на момент старта транзакции. Выбор конкретного уровня изоляции зависит от задач, решаемых транзакцией. 10.2. Реализация механизма транзакций в InterBase Прежде чем перейти непосредственно к описанию работы с транзакциями в InterBase, необходимо разобраться в организации хранения изменений данных в базе и доступа к измененным данным. Для обеспечения изоляции транзакций и, при необходимости, их корректного отката в InterBase помимо измененных данных хранится также и состояние базы до внесения изменений. Другими словами, в базе хранится одновременно несколько версий данных, причем разные транзакции работают с разными версиями. Хранение версий данных в InterBase Прежде всего, отметим, что в отличие от большинства баз данных, InterBase хранит не историю выполнения транзакций, а использует версии строк таблиц, получающихся в результате внесения изменений в базу. При обновлении (update) строки таблицы InterBase сохраняет сначала старое значение строки, а точнее (для экономии объема хранимых данных), разницу между новой и старой строками. Копия сохраняется, если это возможно, на той же странице, что и основные данные, обеспечивая минимизацию времени доступа к сохраненной версии. Затем InterBase заменяет исходную строку новой версией и создает указатель на старую версию (копию). В главную версию строки записывается идентификатор создавшей ее транзакции. Вообще, любая строка таблицы содержит идентификатор создавшей ее транзакции: при создании новой строки в нее помимо самих данных помещается идентификатор создавшей ее транзакции. При удалении строка физически не удаляется, а лишь помечается как удаленная, с указанием идентификатора удаляющей ее транзакции (старое значение с указанием соответствующей транзакции также сохраняется). В случае необходимости отката транзакции достаточно заменить текущее значение строки таблицы на непосредственно предшествующую версию. Идентификаторы транзакциям присваиваются таким образом, что транзакция, которая стартовала позже, будет иметь и больший идентификатор. Чтобы правильно работать с версиями, необходимо располагать информацией о текущем состоянии транзакций. InterBase хранит сведения о текущем состоянии транзакций на специальных страницах базы данных – Transaction Inventory Page (TIP). Транзакция вне зависимости от ее уровня изоляции может находиться в одном из четырех состояний: active, committed, rolled back или in limbo. Текущее состояние транзакции всегда отражается в глобальной TIP. Помимо глобальной TIP существуют также и локальные TIP, используемые транзакциями уровня SNAPSHOT, отражающие состояние TIP на момент их старта. Подробнее о возможных состояниях мы поговорим ниже, а пока ограничимся констатацией того факта, что знание состояния транзакцией необходимо для управления версиями строк таблиц базы. Работа с версиями данных в InterBase В предыдущем разделе мы говорили о механизме создания версий. Каждая транзакция, обновляющая данные, создает новые версии строк таблиц. Если не позаботиться об удалении ненужных версий, то база очень быстро будет состоять только из них и фактически прекратит работу. В первую очередь выясним, сведения о каких транзакциях нам необходимы, чтобы обеспечить корректную работу с версиями, а также удаление заве
Популярное: Почему люди поддаются рекламе?: Только не надо искать ответы в качестве или количестве рекламы... Генезис конфликтологии как науки в древней Греции: Для уяснения предыстории конфликтологии существенное значение имеет обращение к античной... Как выбрать специалиста по управлению гостиницей: Понятно, что управление гостиницей невозможно без специальных знаний. Соответственно, важна квалификация... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (295)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |