Управление транзакциями
На страницу 1, 2 След.
|
Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
storysoft Участник со стажем
Вступление в Клуб: 18.07.2014
|
Пн Июл 20, 2015 14:31  Управление транзакциями |
|
Полезность: Нет оценки
|
Коллеги подскажите: в своей процедуре вызываю две дистрибутивных операции, одна из которых создает клиента, вторая договор РКО к нему. Перед вызовом ставлю точку отката. Пытаюcь откатить создание РКО и клиента (например ошибка) и получаю ошибку, что точка отката 'SP4151697142A$1' никогда не устанавливалась в этом сеансе или является недействительной.
Получается в дистрибутивной процедуре произошел commit.
Можно ли отключить commit в дистрибутивной процедуре? Может какие-то параметры передать? |
|
 |
Alkov Профи
Вступление в Клуб: 23.09.2010
|
Вт Июл 21, 2015 02:16   |
|
Полезность: Нет оценки
|
отключить думаю нет, можно только взять вызов в автономную транзакцию, тогда закоммититься только то что делалось в процедуре, а то что было до её вызова останется незакоммиченым. |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Вт Июл 21, 2015 08:53   |
|
Полезность: Нет оценки
|
Alkov пишет: | отключить думаю нет, можно только взять вызов в автономную транзакцию, тогда закоммититься только то что делалось в процедуре, а то что было до её вызова останется незакоммиченым. |
Теоретически можно пометить транзакцию как READ ONLY, но это приведёт только к исключению в момент commit.
Возможно, в процедуре предусмотрены какие-то параметры, чтобы не делать commit, но для этого нужно хотя бы знать, какую дистрибутивную операцию вы пользуете. |
|
 |
vtar Эксперт
Вступление в Клуб: 20.03.2009
|
Вт Июл 21, 2015 11:30  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
storysoft пишет: | Пытаюcь откатить создание РКО и клиента |
может, в Вашем случае откатывать удалением этих сущностей ? |
|
 |
storysoft Участник со стажем
Вступление в Клуб: 18.07.2014
|
Ср Июл 22, 2015 17:40  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
Откатывать уже нечего, так как в дистрибутивной операции создания рко (например :[RKO].[new#auto_lib]) и клиента произошел commit (причем два раза сначала при создании клиента, потом при создании РКО).
Где вообще в обычной дистрибутивной операции (например создания клиента юрика) прописан commit? Я не нашел. Может где-то в системной части? |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Чт Июл 23, 2015 07:29  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
storysoft пишет: | Откатывать уже нечего, так как в дистрибутивной операции создания рко (например :[RKO].[new#auto_lib]) и клиента произошел commit (причем два раза сначала при создании клиента, потом при создании РКО). |
Я так думаю, что vtar имел в виду Код: | declare rCl ref [CLIENT];
begin
rCl := 234556;
rCl%delete;
end; |
storysoft пишет: | Где вообще в обычной дистрибутивной операции (например создания клиента юрика) прописан commit? Я не нашел. Может где-то в системной части? |
Я так думаю, что commit прописан там, где его прописал разработчик. В каждом случае индивидуально.
Попробуйте сделать свою транзакцию READ ONLY перед вызовом этой операции. |
|
 |
vtar Эксперт
Вступление в Клуб: 20.03.2009
|
Чт Июл 23, 2015 11:29  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
Random пишет: |
Я так думаю, что vtar имел в виду |
Да, всё верно. Получив ссылки созданных объектов, удалить их , раз сложно или невозможно откатить.
COMMIT я так понимаю, генерится Администратором словаря автоматом при компиляции, если не стоит галка "операция контролирует транзакцию", как то так ? |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Чт Июл 23, 2015 13:15  Re: Управление транзакциями |
|
Полезность: 1
|
vtar пишет: | COMMIT я так понимаю, генерится Администратором словаря автоматом при компиляции, если не стоит галка "операция контролирует транзакцию", как то так ? |
Нет.
commit не проставляется автоматом нигде в автогенерируемых операциях.
При вызове операции из ARM Навигатор, после завершения операции выполняется commit - выполняется только в этом случае.
При вызове операции из прикладного кода никакого commit автоматически не делается. Если только операцию не поправили руками и не вставили commit ручками.
Кстати, возможно, этот признак может помочь.
Дело в том, что commit в коде транслируется в вызов служебной библиотеки и там может быть проигнорирован.
Вот что о нём сказано в документации:
Операция контролирует транзакцию
При установленном признаке любые действия при запущенной операции происходят без Commit. По завершении работы операции произойдет подтверждение либо откат всех изменений.
|
|
 |
storysoft Участник со стажем
Вступление в Клуб: 18.07.2014
|
Пт Июл 24, 2015 07:14  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
Random пишет: |
Нет.
commit не проставляется автоматом нигде в автогенерируемых операциях.
При вызове операции из ARM Навигатор, после завершения операции выполняется commit - выполняется только в этом случае.
При вызове операции из прикладного кода никакого commit автоматически не делается. Если только операцию не поправили руками и не вставили commit ручками.
|
Как тогда обяснить что после вызова из прикладного кода дистрибутивной операции (операцию не правили рукми) ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG удаляется точка отката установленная перед эти вызовом??? Значит внутри есть commit. Хотя мои поиски не увенчались успехом. |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Пт Июл 24, 2015 08:05  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
storysoft пишет: |
Как тогда обяснить что после вызова из прикладного кода дистрибутивной операции (операцию не правили рукми) ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG удаляется точка отката установленная перед эти вызовом??? Значит внутри есть commit. Хотя мои поиски не увенчались успехом. |
Да, внутри где-то есть commit;
READ ONLY-транзакция не подходит для поиска commit, к сожалению.
*ушёл думать.
Код: |
declare
idClient number;
idBS number;
idCur number;
vPack varchar2(32767);
z number;
begin
z := rtl.open;
-- Инициализация
select id into idClient from z#cl_priv where rownum <= 1;
select c_SYS_MAIN_VAL into idCur from z#system;
select id into idBS from z#PL_USV where c_fintool = idCur and rownum <= 1;
select package_name into vPack from methods where class_id = 'RKO_INTERFACE' and short_name = 'INT_RKO_OPEN_001';
-- Создаём копии таблиц, чтоб отслеживать создание новых записей в них
execute immediate 'create table b#rko as select id from z#rko';
execute immediate 'create table b#client as select id from z#client';
-- Чтоб проверить, откуда идёт транзакция. Если где-то внутри вызываемых процедур есть commit (не автономный), запись откатить не удастся.
execute immediate 'insert into b#client(id) values(0)';
-- execute immediate 'set transaction read only';
-- dbms_output.put_line(rtl.open);
-- Поехали!
execute immediate 'declare begin
dbms_output.put_line(''new_dog returned ''||'||vPack||'.new_dog('||idClient||', P_ACC_BAL => '||idBS||', P_CONTRACT_CUR => '||idCur||')); end;';
-- выводим разность таблиц
execute immediate 'begin for i in (select id from z#client minus select id from b#client) loop
dbms_output.put_line(''Клиент ''||i.id);
end loop;
for i in (select id from z#rko minus select id from b#rko) loop
dbms_output.put_line(''РКО ''||i.id);
end loop; end;';
-- отслеживаем незафиксированную запись
execute immediate 'begin for i in (select id from b#client where id = 0) loop
dbms_output.put_line(''Клиент 0 существует!'');
end loop;
end;';
-- Rollback!
rollback;
dbms_output.put_line('rollback');
-- Проверяем, что rollback всё вернул на место, как было
execute immediate 'begin for i in (select id from z#client minus select id from b#client) loop
dbms_output.put_line(''Клиент ''||i.id);
end loop;
for i in (select id from z#rko minus select id from b#rko) loop
dbms_output.put_line(''РКО ''||i.id);
end loop; end;';
execute immediate 'begin for i in (select id from b#client where id = 0) loop
dbms_output.put_line(''Клиент 0 существует!'');
end loop;
end;';
-- Удаляем копии таблиц
execute immediate 'drop table b#rko ';
execute immediate 'drop table b#client ';
end;
|
Как видно, до rollback договор есть. Если сделать rollback - он исчезает.
Более того, запись, помещённая в b#client, тоже успешно откатывается!
Последний раз редактировалось: Random (Пн Июл 27, 2015 07:59), всего редактировалось 1 раз |
|
 |
storysoft Участник со стажем
Вступление в Клуб: 18.07.2014
|
Пт Июл 24, 2015 17:43  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
Random пишет: | storysoft пишет: |
Как тогда обяснить что после вызова из прикладного кода дистрибутивной операции (операцию не правили рукми) ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG удаляется точка отката установленная перед эти вызовом??? Значит внутри есть commit. Хотя мои поиски не увенчались успехом. |
Да, внутри где-то есть commit;
READ ONLY-транзакция не подходит для поиска commit, к сожалению.
*ушёл думать.
Код: |
declare
idClient number;
idBS number;
idCur number;
vPack varchar2(32767);
z number;
begin
z := rtl.open;
select id into idClient from z#cl_priv where rownum <= 1;
select c_SYS_MAIN_VAL into idCur from z#system;
select id into idBS from z#PL_USV where c_fintool = idCur and rownum <= 1;
execute immediate 'create table b#rko as select id from z#rko';
execute immediate 'create table b#client as select id from z#client';
execute immediate 'insert into b#client(id) values(0)';
-- execute immediate 'set transaction read only';
-- dbms_output.put_line(rtl.open);
select package_name into vPack from methods where class_id = 'RKO_INTERFACE' and short_name = 'INT_RKO_OPEN_001';
execute immediate 'declare begin
dbms_output.put_line(''new_dog returned ''||'||vPack||'.new_dog('||idClient||', P_ACC_BAL => '||idBS||', P_CONTRACT_CUR => '||idCur||')); end;';
execute immediate 'begin for i in (select id from z#client minus select id from b#client) loop
dbms_output.put_line(''Клиент ''||i.id);
end loop;
for i in (select id from z#rko minus select id from b#rko) loop
dbms_output.put_line(''РКО ''||i.id);
end loop; end;';
execute immediate 'begin for i in (select id from b#client where id = 0) loop
dbms_output.put_line(''Клиент 0 существует!'');
end loop;
end;';
rollback;
dbms_output.put_line('rollback');
execute immediate 'begin for i in (select id from z#client minus select id from b#client) loop
dbms_output.put_line(''Клиент ''||i.id);
end loop;
for i in (select id from z#rko minus select id from b#rko) loop
dbms_output.put_line(''РКО ''||i.id);
end loop; end;';
execute immediate 'begin for i in (select id from b#client where id = 0) loop
dbms_output.put_line(''Клиент 0 существует!'');
end loop;
end;';
execute immediate 'drop table b#rko ';
execute immediate 'drop table b#client ';
end;
|
Как видно, до rollback договор есть. Если сделать rollback - он исчезает.
Более того, запись, помещённая в b#client, тоже успешно откатывается! |
Совсем запутался, если в операции ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG есть commit то как rollback откатил?? |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Пн Июл 27, 2015 07:54  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
storysoft пишет: | Совсем запутался, если в операции ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG есть commit то как rollback откатил?? |
Я не уверен, что он есть, но точно, что Вы запутались. |
|
 |
storysoft Участник со стажем
Вступление в Клуб: 18.07.2014
|
Пн Июл 27, 2015 12:15  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
Random пишет: | storysoft пишет: | Совсем запутался, если в операции ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG есть commit то как rollback откатил?? |
Я не уверен, что он есть, но точно, что Вы запутались. |
В одном я 100% уверен: точка отката установленная через &sp(a#01)
"исчезает" после ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG.
На клманду &rb(a#01) получаю ошибку (точка отката 'SP4151697142A$1' никогда не устанавливалась в этом сеансе или является недействительной).
Может это связано с особенностью реализации в ЦФТ.
Что вообще делают процедуры?
cache_mgr.cache_set_savepoint ('SP9455837668A#01');
cache_mgr.cache_rollback('SP9455837668A#01'); |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Пн Июл 27, 2015 12:28  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
storysoft пишет: | Random пишет: | storysoft пишет: | Совсем запутался, если в операции ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG есть commit то как rollback откатил?? |
Я не уверен, что он есть, но точно, что Вы запутались. |
В одном я 100% уверен: точка отката установленная через &sp(a#01)
"исчезает" после ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG.
На клманду &rb(a#01) получаю ошибку (точка отката 'SP4151697142A$1' никогда не устанавливалась в этом сеансе или является недействительной).
Может это связано с особенностью реализации в ЦФТ.
Что вообще делают процедуры?
cache_mgr.cache_set_savepoint ('SP9455837668A#01');
cache_mgr.cache_rollback('SP9455837668A#01'); |
Ни пакет cache_mgr, ни cache_service не являются заврапленными и Вы легко можете посмотреть, что же они делают. |
|
 |
timochev Эксперт
Вступление в Клуб: 02.07.2007
|
Пн Июл 27, 2015 14:31  Re: Управление транзакциями |
|
Полезность: Нет оценки
|
storysoft пишет: |
В одном я 100% уверен: точка отката установленная через &sp(a#01)
"исчезает" после ::[RKO_INTERFACE].[INT_RKO_OPEN_001].NEW_DOG.
|
Текст процедуры - в студию.
В Вашей процедуре случайно нет DDL, как в примере у Random?
Цитата: | Oracle Database issues an implicit COMMIT under the following circumstances:
Before any syntactically valid data definition language (DDL) statement, even if the statement results in an error
After any data definition language (DDL) statement that completes without an error
|
|
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|