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

Откуда:
Сообщений: 143
Занятно

Выполняем в одной сессии:

SQL*Plus: Release 11.2.0.3.0 Production on Thu Aug 30 19:10:32 2012

Copyright (c) 1982, 2011, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options

someuser@somebase> drop table test_lock1;

Table dropped.

someuser@somebase> create table test_lock1 (id1 number, a1 number);

Table created.

someuser@somebase> insert into test_lock1 values(1,1);

1 row created.

someuser@somebase> drop table test_lock2;

Table dropped.

someuser@somebase> create table test_lock2 (id2 number, a2 number);

Table created.

someuser@somebase> select * from test_lock1 left join test_lock2 on  test_lock1.id1=test_lock2.id2 for update of test_lock1.a1;

       ID1         A1        ID2         A2
---------- ---------- ---------- ----------
         1          1


В этот момент в другой:

someuser@somebase>  select * from test_lock1 left join test_lock2 on  test_lock1.id1=test_lock2.id2 for update of test_lock1.a1

, которая, соответственно, зависает в ожидании разблокировки

Далее, в 1-ой сессии:

someuser@somebase> insert into test_lock2 values(1,1);

1 row created.

someuser@somebase> update test_lock1 set test_lock1.a1=2 where test_lock1.id1=1;

1 row updated.

someuser@somebase> commit;

Commit complete.


А отвисшая вторая нас вводит в состояние когнитивного диссонанса:

someuser@somebase>  select * from test_lock1 left join test_lock2 on  test_lock1.id1=test_lock2.id2 for update of test_lock1.a1;

       ID1         A1        ID2         A2
---------- ---------- ---------- ----------
         1          2


Я о чем? А о том, что запрос во второй сессии нам вернул данные из второй таблицы на момент его начала, а из первой - на момент разблокировки... Не в противоречии ли это с концепциями?
30 авг 12, 20:29    [13091586]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
Allbest,

нет, и пример будет понятнее так:
-- в первой сессии:
create table t1 as select * from xmltable('1 to 3' columns a number path '.');
DB11G/XTENDER> select * from t1 where a=1 for update;

         A
----------
         1

1 row selected.
-- теперь во второй:
DB11G/XTENDER> select * from t1 where a=1 for update;
-- висим...

-- снова в первой:
DB11G/XTENDER> update t1 set a=1;

3 rows updated.

Elapsed: 00:00:00.02
DB11G/XTENDER> commit;

Commit complete.

Elapsed: 00:00:00.00
-- во второй получаем:
DB11G/XTENDER> select * from t1 where a=1 for update;

         A
----------
         1

1 row selected.
30 авг 12, 21:07    [13091677]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
Allbest,

В противоречии, полученный результат не соответствует никакому scn. Подобный пример я уже приводил как-то с update t set a = a + 1 где после отвисания, update видит измененное значение поля, но не видит свежевставленную строку.
30 авг 12, 23:10    [13092046]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
был не прав, каюсь :) _Nikotin терпеливо дождался моего понимания, что рестарта не было :)
у for update вообще row level restart'ы бывают?
30 авг 12, 23:36    [13092147]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
_Nikotin,

Если кто-то думает что тут есть рестарт, то его тут нет, если бы он был то результат был бы согласован.
30 авг 12, 23:36    [13092148]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
и ведь самое смешное, что специально делал себе заметку об этом поведении: http://www.xt-r.com/2011/12/select-for-update-of.html
30 авг 12, 23:40    [13092156]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
andrey_anonymous
Именно так, см. "эскперимент1". Скажу больше - если новое значение поля будет совпадать со старым, то рестарта тоже не будет, даже если измененное поле упомянуто в запросе.

стоит уточнить, что речь про предикатное поле
30 авг 12, 23:46    [13092180]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
Allbest
Member

Откуда:
Сообщений: 143
_Nikotin
В противоречии, полученный результат не соответствует никакому scn.

Считать багой или фичей? Есть что-либо об этом в документации?
30 авг 12, 23:59    [13092225]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
Allbest,

Если по строгости закона то вопиющим багом, так как нет обещанной согласованности.
31 авг 12, 00:13    [13092269]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
В 11.2.0.1 вообще жестко получается уже на середине теста )))

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 
Connected as tst
 
SQL> 
SQL> drop table test_lock1;
 
Table dropped
SQL> create table test_lock1 (id1 number, a1 number);
 
Table created
SQL> insert into test_lock1 values(1,1);
 
1 row inserted
SQL> drop table test_lock2;
 
Table dropped
SQL> create table test_lock2 (id2 number, a2 number);
 
Table created
SQL> select * from test_lock1 left join test_lock2 on  test_lock1.id1=test_lock2.id2 for update of test_lock1.a1;
 
       ID1         A1        ID2         A2         A1
---------- ---------- ---------- ---------- ----------
         1          1                                1
 
SQL> select * from test_lock1, test_lock2 where test_lock1.id1 = test_lock2.id2 (+) for update of test_lock1.a1;
 
       ID1         A1        ID2         A2
---------- ---------- ---------- ----------
         1          1  
31 авг 12, 01:21    [13092392]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
_Nikotin
Если по строгости закона то вопиющим багом, так как нет обещанной согласованности.


Конечно хотелось бы более конкретного обьяснения, но неявно поведение SELECT FOR UPDATE следует из:

By default, the SELECT FOR UPDATE statement waits until the requested row lock is acquired.

SY.
31 авг 12, 01:44    [13092417]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
До завтра уже не проверю, но интересео как скажется buffer sort на чтении после рестарта приджойненных таблиц или подзапрлсов
31 авг 12, 01:45    [13092418]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
На самом деле если селект во второй сессии запустить после вставки в первой он увидит эти строки
Это уже ни в какие ворота.
31 авг 12, 01:53    [13092429]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
Allbest
Member

Откуда:
Сообщений: 143
SY
Конечно хотелось бы более конкретного обьяснения, но неявно поведение SELECT FOR UPDATE следует из:
SY.

Дело в том, что настолько неявно, что фиг проссышь....
Второй эксперимент:
1-ая сессия:

SQL*Plus: Release 11.2.0.3.0 Production on Fri Aug 31 02:07:01 2012
Copyright (c) 1982, 2011, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options

someuser@somebase> drop table test_lock1;
Table dropped.
someuser@somebase> create table test_lock1 (id1 number, a1 number);
Table created.
someuser@somebase> insert into test_lock1 values(1,1);
1 row created.
someuser@somebase>
someuser@somebase> drop table test_lock2;
Table dropped.
someuser@somebase> create table test_lock2 (id2 number, a2 number);
Table created.
someuser@somebase> insert into test_lock2 values(1,1);
1 row created.
someuser@somebase> commit;
Commit complete.

someuser@somebase> select * from test_lock1, test_lock2 for update of test_lock1.a1;

       ID1         A1        ID2         A2
---------- ---------- ---------- ----------
         1          1          1          1


2-ая сессия:

someuser@somebase> create or replace function test_me(p_num in number) return number is
  2  begin
  3    dbms_output.put_line(to_char(sysdate, 'dd.mm.rr HH24:MI:SS'));
  4    return 1;
  5  end test_me;
  6  /

Function created.

someuser@somebase> select * from test_lock2, test_lock1 where test_me(test_lock1.id1)=1 for update of test_lock1.a1;

(висим)

1-ая:

someuser@somebase> update test_lock2 set test_lock2.a2=2 where test_lock2.id2=1;
1 row updated.
someuser@somebase> update test_lock1 set test_lock1.a1=2 where test_lock1.id1=1;
1 row updated.
someuser@somebase> commit;
Commit complete.


и вновь 2-ая:


someuser@somebase> select * from test_lock2, test_lock1 where test_me(test_lock1.id1)=1 for update of test_lock1.a1;

       ID2         A2        ID1         A1
---------- ---------- ---------- ----------
         1          2          1          2

31.08.12 02:22:16
31.08.12 02:22:45
someuser@somebase>


Т.е. в настоящем примере наблюдаем, какбэ, рестарт, и получаем то, что, однако, хотим
31 авг 12, 02:24    [13092460]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
Нет в жизни справедливости ....

======================= test1

--первая сессия 
drop table xxx purge;
create table xxx (id number,val number);
insert into xxx values (1, 1);
commit;
update xxx set val = val + 1;
insert into xxx values (2, 1);
-- вторая сессия
update xxx set val = val + 1;
select * from xxx;
-- первая
commit;
-- вторая

        ID        VAL
---------- ----------
         1          3
         2          1
         
======================= test2

--первая сессия 
drop table xxx purge;
create table xxx (id number,val number);
insert into xxx values (1, 1);
commit;
insert into xxx values (2, 1);
update xxx set val = val + 1;
-- вторая сессия
update xxx set val = val + 1;
select * from xxx;
-- первая
commit;
-- вторая

        ID        VAL
---------- ----------
         1          3
         2          2
31 авг 12, 02:34    [13092467]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
_Nikotin,

в пятницу блин эту тему надо было обсуждать
31 авг 12, 02:37    [13092469]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
оопс, в последнем это мне спать пора, не заметил как в первой сессии апдейт вставленную строку обновил.
31 авг 12, 02:41    [13092471]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
xtender,

А у меня пятница - выходной (да у по-любому у нас уже пятница).
31 авг 12, 02:43    [13092472]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
_Nikotin,

через 5 часов уже ребенка в сад отводить :(
31 авг 12, 02:44    [13092473]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
xtender,

Если он останется дома поспать до 11, думаю только спасибо скажет ))
31 авг 12, 02:46    [13092474]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
Allbest
Member

Откуда:
Сообщений: 143
_Nikotin
Нет в жизни справедливости ....

Ну да, в Вашем примере, слава сОтоне, все похоже на правду :) иначе пришлось убить бы себя об ближайшую стену :) видимо, и в самом деле, глыбокий ночь пришел
31 авг 12, 02:52    [13092476]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
Allbest,

Но если ваш пример поправить, то совсем худо:

------------------- TEST 1
-- session 1
drop table test_lock1;
drop table test_lock2;
create table test_lock1 as select 1 id1, 1 a1 from dual;
create table test_lock2 as select 1 id2, 1 a2 from dual where 1 = 2;
commit;
update test_lock1 set a1=2 where id1=1;
-- session 2
select * from test_lock1, test_lock2 where id2 (+) = id1 for update of a1;
-- session 1
insert into test_lock2 values(1,1);
commit;
-- session 2
SQL> select * from test_lock1, test_lock2 where id2 (+) = id1 for update of a1;
 
       ID1         A1        ID2         A2
---------- ---------- ---------- ----------
         1          2    

------------------- TEST 2
-- session 1
drop table test_lock1;
drop table test_lock2;
create table test_lock1 as select 1 id1, 1 a1 from dual;
create table test_lock2 as select 1 id2, 1 a2 from dual where 1 = 2;
commit;
update test_lock1 set a1=2 where id1=1;
insert into test_lock2 values(1,1);
-- session 2
select * from test_lock1, test_lock2 where id2 (+) = id1 for update of a1;
-- session 1
commit;
-- session 2
SQL> select * from test_lock1, test_lock2 where id2 (+) = id1 for update of a1;
 
       ID1         A1        ID2         A2
---------- ---------- ---------- ----------
         1          2          1          1
31 авг 12, 03:00    [13092478]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
На 11.2.0.3 не повторяется последнее, да и ваш пример не повторяется, я ставил отсюда p10404530_112030_Linux-x86-64, никакие патчи поверх не накатывал.
31 авг 12, 03:09    [13092482]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
_Nikotin
Это уже ни в какие ворота.


Наоборот, это прямо соответствует "By default, the SELECT FOR UPDATE statement waits until the requested row lock is acquired". Так будет понятней:

Сессия 1:

SQL> select * from test_lock1 where id1 = 1 for update;

       ID1         A1
---------- ----------
         1          1


Сессия 2:

SQL> select * from test_lock1 where id1 = 1 for update;


и ждет. Возвращаемся к сессии 1:

SQL> update test_lock1 set id1 = 3;

1 row updated.

SQL> commit;

Commit complete.

SQL> 


И сессия 2 выдает:

no rows selected

SQL> 


Еще пример:

Сессия 1:

SQL> drop table test_lock1 purge;

Table dropped.

SQL> create table test_lock1 (id1 number, a1 number);

Table created.

SQL> insert into test_lock1 values(1,1);

1 row created.

SQL> commit;

Commit complete.

SQL> select * from test_lock1 where id1 = 1 for update;

       ID1         A1
---------- ----------
         1          1


Сессия 2:

SQL> select * from test_lock1 where id1 = 1 for update;


и ждет. Возвращаемся к сессии 1:

SQL> update test_lock1 set id1 = 3;

1 row updated.

SQL> insert into test_lock1 values(1,2);

1 row created.

SQL> commit;

Commit complete.

SQL> 


И сессия 2 выдает:

       ID1         A1
---------- ----------
         1          2

SQL> 


Еще раз, SELECT FOR UPDATE пытается повесить lock на потенциальные строки до выполнения самого SELECTa. Сам SELECT начинается после. Где-то на форуме обсуждался SKIP LOCKED. Там, если не ошибаюсь, это тоже обсуждалось c точки зрения рестарта.

SY.

Сообщение было отредактировано: 31 авг 12, 03:22
31 авг 12, 03:18    [13092483]     Ответить | Цитировать Сообщить модератору
 Re: Согласованность данных в запросе с for update  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
SY
SELECT FOR UPDATE пытается повесить lock на потенциальные строки до выполнения самого SELECTa. Сам SELECT начинается после.


Упс. Имел ввиду до выполнения FETCHa. Сам FETCH начинается после.

SY.
31 авг 12, 03:40    [13092486]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Oracle Ответить