Мегаобучалка Главная | О нас | Обратная связь


Динамическое формирование операторов SQL на этапе выполнения



2019-07-03 295 Обсуждений (0)
Динамическое формирование операторов SQL на этапе выполнения 0.00 из 5.00 0 оценок




В процессе своей работы 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 соз­да­ет роль в ба­зе дан­ных.

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> on [table] <tname> | execute on procedure <procname>}
to {<list_object> | <userlist> | group <unix_group>}
| <role_granted> to {public | <role_grantee_list>};

<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>]
 [with grant option]

<role_granted> ::= <rolename> [,<role_granted>]

<role_grantee_list> ::= [user] <username> [,<role_grantee_list>]
[with admin option]

<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]{
{all [privileges] | select | delete | insert | update [(col [, col ...])]}
on [table] <tname> from {<object> | <userlist>}
| execute on procedure <procname> from {<object> | <userlist>}};

Все параметры команды имеют тот же смысл, что и в команде 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

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

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



2019-07-03 295 Обсуждений (0)
Динамическое формирование операторов SQL на этапе выполнения 0.00 из 5.00 0 оценок









Обсуждение в статье: Динамическое формирование операторов SQL на этапе выполнения

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Почему люди поддаются рекламе?: Только не надо искать ответы в качестве или количестве рекламы...
Генезис конфликтологии как науки в древней Греции: Для уяснения предыстории конфликтологии существенное значение имеет обращение к античной...
Как выбрать специалиста по управлению гостиницей: Понятно, что управление гостиницей невозможно без специальных знаний. Соответственно, важна квалификация...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (295)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.02 сек.)