Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 кто инвалидирует курсор?  [new]
Allbest
Member

Откуда:
Сообщений: 118
Приветствую, уважаемые!
Решаю следующую проблему
Eсть процедура типа:

procedure test (p_id pls_integer) is
cursor l_c is select * from table1 t1 where t1.id1=p_id for update of t1.some_col;
l_rec l_c%type;
--TEST
l_rb pls_integer:=0;
--
begin
open l_c;
loop
fetch l_c into l_rec;
exit when l_c%notfound;
--TEST BLOCK
dbms_output.put_line('TR_ID:' || dbms_transaction.local_transaction_id);
select m.value-l_rb into l_rb from v$mystat m where m.statistic# = 188;
dbms_output.put_line(sys.diutil.bool_to_int(l_c%found));
--
another_procedure(...);
--TEST BLOCK
dbms_output.put_line('TR_ID:' || dbms_transaction.local_transaction_id);
select m.value-l_rb into l_rb from v$mystat m where m.statistic# = 188;
dbms_output.put_line(sys.diutil.bool_to_int(l_c%found));
--
update table1 t1 set t1.some_col=some_val where current of l_c;--ORA-01410 Invalid rowid
end loop;
dbms_output.put_line('Rollback applied:' || l_rb);

end;

В указанной в процедуре строке вываливаемся на ошибку ORA-01410 Invalid rowid
Что характерно, если заблокировать заблокировать вызов another_procedure(...), то все будет в порядке
Дополнительная информация на съедение
В тестовых блоках проверятся
а)идентификатор текущей транзакции: он остается неизменным после возвращения из another_procedure(...)
б)анализируется применение всевозможных ролбэков по сэйвпойнтам и тд на основании данных из статистики : вывод сделан, что роллбэков в процедуре another_procedure(...) не случается.
в)смотрится параметр курсора %found. Любопытно то, что на выходе из процедуры
%found=null (как это бывает после открытия курсора, но до извлечения первой записи)

Стэк вызовов достаточно нетривиален. Каскад вызовов идет из another_procedure, в том числе рекурсивный вызов рассматриваемой процедуры, поэтому отследить момент "инвалидации" курсора достаточно сложно.
Ваши мнения?
8 дек 09, 14:06    [8034855]     Ответить | Цитировать Сообщить модератору
 Re: кто инвалидирует курсор?  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 28960
  • Банально: удалили строку (а потом вставили).
  • Перенесли в другую partition.
  • ...
  • 8 дек 09, 14:28    [8035098]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    andrey_anonymous
    Member

    Откуда: Москва
    Сообщений: 17322
    Elic
  • Банально: удалили строку (а потом вставили).
  • Перенесли в другую partition.
  • ...

  • Попробуй сначала :)
    Я уже пол-мозга себе вынес, но именно invalid rowid получить пока не смог :)
    8 дек 09, 14:49    [8035328]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    andrey_anonymous
    Member

    Откуда: Москва
    Сообщений: 17322
    andrey_anonymous

    Я уже пол-мозга себе вынес, но именно invalid rowid получить пока не смог :)

    Уточнение: не прерывая основной транзакции.
    8 дек 09, 14:50    [8035337]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Allbest
    Member

    Откуда:
    Сообщений: 118
    andrey_anonymous
    andrey_anonymous

    Я уже пол-мозга себе вынес, но именно invalid rowid получить пока не смог :)

    Уточнение: не прерывая основной транзакции.


    чистая правда, "выношу мозг" уже пол дня.. без результатов

    правда, ошибся нюансом в изначальном определении задачи, но, думаю, это не существенно.
    delete where current of надо заменить update .. where current of
    8 дек 09, 15:05    [8035506]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    andrey_anonymous
    Member

    Откуда: Москва
    Сообщений: 17322
    Allbest
    чистая правда, "выношу мозг" уже пол дня.. без результатов

    Если это не досрочная пятничная задачка, то снимите и покажите трассу (неформатированную, level 1 подойдет).
    8 дек 09, 15:10    [8035554]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Elic
    Member

    Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
    Сообщений: 28960
    andrey_anonymous
    Попробуй сначала :)
    Таки не вышло :)
    8 дек 09, 15:39    [8035890]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    dmitrysk
    Member

    Откуда:
    Сообщений: 460
    А чего в процедуре another_procedure делаете?
    8 дек 09, 15:44    [8035943]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Leshy
    Member

    Откуда:
    Сообщений: 6
    andrey_anonymous,

    SQL> drop table test
    2 /

    Table dropped.

    SQL> create table test (a number)
    2 /

    Table created.

    SQL> insert into test values (1)
    2 /

    1 row created.

    SQL> commit
    2 /

    Commit complete.

    SQL> declare
    2 cursor c is select * from test for update;
    3 begin
    4 open c;
    5 loop
    6 delete from test where current of c;
    7 update test set a = 2 where current of c;
    8 end loop;
    9 end;
    10 /
    declare
    *
    ERROR at line 1:
    ORA-01410: invalid ROWID
    ORA-06512: at line 6
    8 дек 09, 16:04    [8036164]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Elic
    Member

    Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
    Сообщений: 28960
    Leshy
    А fetch-ить пушкин будет? :)
    8 дек 09, 16:10    [8036209]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Leshy
    Member

    Откуда:
    Сообщений: 6
    Elic
    А fetch-ить пушкин будет? :)


    :) а зачем?

    да, с фетчем все по-другому выглядит
    8 дек 09, 16:15    [8036263]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    K790
    Member

    Откуда:
    Сообщений: 611
    Leshy,

    похоже на то. либо в процедуре another_procedure(...); не закоммичены dml, либо не закрыт курсор, хотя там была бы другая ошибка.
    8 дек 09, 16:20    [8036300]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Elic
    Member

    Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
    Сообщений: 28960
    Leshy
    Elic
    А fetch-ить пушкин будет? :)
    :) а зачем?
    Ты уверен, что вниматильно читал исходный прототип кода?
    8 дек 09, 16:33    [8036414]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Allbest
    Member

    Откуда:
    Сообщений: 118
    В another_procedure что только не делается... В том числе, как уже заметил, рекурсивные вызовы рассматриваемой процедуры
    Вообще, появились некоторые мысЕли по способу распутывания сиих злономеренных козней :) Отпишусь позже
    В том числе выложу трэйс, если понадобится, очистив от бизнес-инфы :)
    8 дек 09, 16:35    [8036432]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    andrey_anonymous
    Member

    Откуда: Москва
    Сообщений: 17322
    Allbest
    рекурсивные вызовы рассматриваемой процедуры

    ух ты...
    Интересная идея, но времени на эксперименты уже нет :(
    8 дек 09, 16:38    [8036459]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Хохлов
    Member

    Откуда:
    Сообщений: 1169
    Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 
    Connected as test1
     
    SQL> select t.owner,t.table_name from all_tables t where t.table_name = 'TABLE1';
     
    OWNER                          TABLE_NAME
    ------------------------------ ------------------------------
    TEST1                          TABLE1
    TEST2                          TABLE1
     
    SQL> set serveroutput on
    SQL> 
    SQL> declare
      2    cursor l_c is
      3      select * from table1 t1 where t1.id1 = 1 for update of t1.some_col;
      4    l_rec l_c%rowtype;
      5    --TEST
      6    l_rb pls_integer := 0;
      7    --
      8    procedure another_procedure
      9    is
     10    begin
     11      execute immediate 'alter session set current_schema=TEST2';
     12      null;
     13    end;
     14  begin
     15    dbms_output.enable;
     16    open l_c;
     17    loop
     18      fetch l_c
     19        into l_rec;
     20      exit when l_c%notfound;
     21      --TEST BLOCK
     22      dbms_output.put_line('TR_ID:' || dbms_transaction.local_transaction_id);
     23      select m.value - l_rb
     24        into l_rb
     25        from v$mystat m
     26       where m.statistic# = 228;
     27      dbms_output.put_line(sys.diutil.bool_to_int(l_c%found));
     28      --
     29      another_procedure;
     30      --TEST BLOCK
     31      dbms_output.put_line('TR_ID:' || dbms_transaction.local_transaction_id);
     32      select m.value - l_rb
     33        into l_rb
     34        from v$mystat m
     35       where m.statistic# = 228;
     36      dbms_output.put_line(sys.diutil.bool_to_int(l_c%found));
     37      --
     38      begin
     39      update table1 t1 set t1.some_col = 1 where current of l_c; --ORA-01410 Invalid rowid
     40       exception when others then
     41        dbms_output.put_line(SQLERRM);
     42      end;
     43    end loop;
     44    dbms_output.put_line('Rollback applied:' || l_rb);
     45  end;
     46  /
     
    TR_ID:38.2.285
    1
    TR_ID:38.2.285
    1
    ORA-01410: invalid ROWID
    Rollback applied:0
     
    PL/SQL procedure successfully completed
     
    SQL> 
    8 дек 09, 18:15    [8037290]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    andrey_anonymous
    Member

    Откуда: Москва
    Сообщений: 17322
    Хохлов, браво!
    Если гора не идет к Магомеду, то Магомед идет к горе - я не додумался :)
    8 дек 09, 18:17    [8037306]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Elic
    Member

    Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
    Сообщений: 28960
    andrey_anonymous
    Хохлов, браво!
    Если гора не идет к Магомеду, то Магомед идет к горе - я не додумался :)
    Это можно было бы считать версией, если бы процедура автора была authid current_user. Ставлю на то, что это не так :)
    8 дек 09, 19:12    [8037483]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    andrey_anonymous
    Member

    Откуда: Москва
    Сообщений: 17322
    Elic
    andrey_anonymous
    Хохлов, браво!
    Если гора не идет к Магомеду, то Магомед идет к горе - я не додумался :)
    Это можно было бы считать версией, если бы процедура автора была authid current_user. Ставлю на то, что это не так :)

    Виталь, попробуй что-ли...
    Ни при чем тут authid.
    Тут играет рояль момент, в который открывается/парсится курсор update.
    8 дек 09, 19:31    [8037540]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    andrey_anonymous
    Member

    Откуда: Москва
    Сообщений: 17322
    andrey_anonymous

    Ни при чем тут authid.

    уточнение: пример не требует authid current_user.
    требуется только грант на update таблицы соседней схемы
    8 дек 09, 19:33    [8037545]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Хохлов
    Member

    Откуда:
    Сообщений: 1169
    Мне тоже что-то подсказывает, что это не случай ТС...
    Вроде ситуация воспроизведена, но осадок остался...
    P.S. Думаю, что ТС расставит все точки над Ы
    8 дек 09, 19:42    [8037574]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Elic
    Member

    Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
    Сообщений: 28960
    andrey_anonymous
    Тут играет рояль момент, в который открывается/парсится курсор update.уточнение: пример не требует authid current_user.
    требуется только грант на update таблицы соседней схемы
    Тебе, похоже, пора перечитывать "Who Is the Current User During Subprogram Execution?":
    + definer
    create view user_users as select * from dual;
    
    create procedure tmp_proc
    as
    begin
      execute immediate 'alter session set current_schema=sys';
      for x in (select * from user_users) loop
        dbms_output.put_line(x.dummy);
      end loop;
    end;
    /
    exec tmp_proc
    
    X
    
    PL/SQL procedure successfully completed.
    
    + current_user
    exec execute immediate 'alter session set current_schema='||user
    
    create or replace procedure tmp_proc authid current_user
    as
    begin
      execute immediate 'alter session set current_schema=sys';
      for x in (select * from user_users) loop
        dbms_output.put_line(x.dummy);
      end loop;
    end;
    /
    exec tmp_proc
    
    BEGIN tmp_proc; END;
    
    *
    ERROR at line 1:
    ORA-00932: inconsistent datatypes: expected - got -
    ORA-06512: at "OWNER.TMP_PROC", line 5
    ORA-06512: at line 1
    exec execute immediate 'alter session set current_schema='||user
    
    begin
      for x in (select * from user_users) loop
        dbms_output.put_line(x.dummy);
      end loop;
      execute immediate 'alter session set current_schema=sys';
      for x in (select * from user_users) loop
        dbms_output.put_line(x.dummy);
      end loop;
    end;
    /
    
    X
    begin
    *
    ERROR at line 1:
    ORA-00932: inconsistent datatypes: expected - got -
    ORA-06512: at line 6
    exec execute immediate 'alter session set current_schema='||user
    drop procedure tmp_proc;
    drop view user_users;
    
    select * from user_users;
    
    8 дек 09, 19:58    [8037614]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Allbest
    Member

    Откуда:
    Сообщений: 118
    Хохлов
    Спасибо, уже гораздо ближе (вероятно) к истине, НО хотел бы обратить внимание на другой важный момент, который не воспроизведен и поэтому, думаю, это не совсем то:
    dbms_output.put_line(sys.diutil.bool_to_int(l_c%found));
    ...
    TR_ID:38.2.285
    1
    TR_ID:38.2.285
    1
    
    Обратите внимание на постановку %found=null при выходе из another_procedure ...
    Дополнительное наблюдение: искомый rowid по-прежнему существует и после пресловутой another_procedure
    8 дек 09, 20:06    [8037634]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    andrey_anonymous
    Member

    Откуда: Москва
    Сообщений: 17322
    Elic
    andrey_anonymous
    Тут играет рояль момент, в который открывается/парсится курсор update.уточнение: пример не требует authid current_user.
    требуется только грант на update таблицы соседней схемы
    Тебе, похоже, пора

    Elic, специально для тебя:
    conn USER2
    create table ane_t(id,u) as select 1, user from dual;
     
    Table created
    
    grant all on ane_t to user1;
     
    Grant succeeded
    
    conn USER1
    
    create table ane_t(id,u) as select 1, user from dual;
     
    Table created
    
    declare
      cursor c1 is select rowid rid, t.* from ane_t t;
      cursor c2 is select rowid rid, t.* from ane_t t;
      l_row c1%rowtype;
      l_row2 c1%rowtype;
    begin
      open c1;
      execute immediate 'alter session set current_schema=user2';
      open c2;
      fetch c1 into l_row;
      fetch c2 into l_row2;
      close c2;
      close c1;
      dbms_output.put_line('c1:'||l_row.rid||','||l_row.u);
      dbms_output.put_line('c2:'||l_row2.rid||','||l_row2.u);
    end;
    /
     
    c1:AAAeOsAAeAAF06sAAA,USER1
    c2:AAAeOrAAdAADpwSAAA,USER2
     
    PL/SQL procedure successfully completed
     
    SQL> 
    8 дек 09, 20:08    [8037637]     Ответить | Цитировать Сообщить модератору
     Re: кто инвалидирует курсор?  [new]
    Allbest
    Member

    Откуда:
    Сообщений: 118
    Elic
    andrey_anonymous
    Хохлов, браво!
    Если гора не идет к Магомеду, то Магомед идет к горе - я не додумался :)
    Это можно было бы считать версией, если бы процедура автора была authid current_user. Ставлю на то, что это не так :)

    Ставка принята ;-) Размер ставки?
    Вы правы
    8 дек 09, 20:09    [8037639]     Ответить | Цитировать Сообщить модератору
    Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
    Все форумы / Oracle Ответить