PLSQL Oracle 12c тупик, почему блокировка таблицы SSX используется для независимого удаления? - PullRequest
1 голос
/ 19 апреля 2019

У меня есть два следующих запроса, которые приводят к тупику.Но не знаю, почему Oracle пытается установить блокировку таблицы SSX в этом сценарии.

Все тестовые примеры пытались воспроизвести проблему, делают только блокировку строк.

                                          ------------Blocker(s)-----------  ------------Waiter(s)------------
Resource Name                             process session holds waits serial  process session holds waits serial
TM-000386AF-00000000-00000000-00000000        101     298    SX   SSX  65474      27     646    SX   SSX  21533
TM-000386AF-00000000-00000000-00000000         27     646    SX   SSX  21533     101     298    SX   SSX  65474


Query:
DELETE FROM VERSANDPALETTE V WHERE V.ID IN (SELECT COLUMN_VALUE FROM TABLE(:B1 ))


----- Information for the OTHER waiting sessions -----
Session 646:
DELETE FROM VERSANDPALETTE WHERE ID IN (SELECT * FROM TABLE(:B1 )) AND ID NOT IN (SELECT * FROM TABLE(:B2 ))

Я ожидаю,что независимые наборы строк удаляются и таблица не блокируется.

Есть ли у кого-нибудь подсказка о том, почему это может произойти?

РЕДАКТИРОВАТЬ 2: (Упрощенная версия вопроса, 2минута для репликации)

Спасибо за вашу помощь!

Я использовал этот код для дальнейшего тестирования:

-- setup
create table p ( x int primary key );
create table c ( x references p );
insert into p select rownum from dual connect by level <= 10;
insert into c select * from p;
commit;
-- 2 session test

-- session 1
update c set x = 2 where x = 1;

-- session 2
update c set x = 4 where x = 3;
delete from p where x = 3;

-- session 1
delete from p where x = 1;

-- deadlock is happening now

-- rollback both sessions

Это приводит к тупикукак и ожидалось, потому что нет индекса на дочерней таблице fk.(как вы указали мне)

Что меня смущает, так это то, что когда используется только одна сессия, открываются только locked_mode 3 v $ locked_object.Где-то должна быть строка locked_mode 5.

-- 1 session test
update c set x = 2 where x = 1;
update c set x = 4 where x = 3;
delete from p where x = 3;
delete from p where x = 1;

select
c.owner,
c.object_name,
c.object_type,
b.sid,
b.serial#,
b.status,
b.osuser,
b.machine,
a.locked_mode
from
v$locked_object a ,
v$session b,
dba_objects c
where
b.sid = a.session_id 
and
a.object_id = c.object_id;

-- no locked_mode 5 entries...
-- rollback the session

Добавление индекса решает проблему:

CREATE INDEX c_index ON c(x);

-- 2 session test
-- session 1
update c set x = 2 where x = 1;

-- session 2
update c set x = 4 where x = 3;
delete from p where x = 3;

-- session 1
delete from p where x = 1;

-- deadlock is not happening :)

Итак, я предполагаю, что происходит некоторое повышение блокировки?Потому что тест с одним сеансом не требует той же блокировки таблицы.

1 Ответ

2 голосов
/ 19 апреля 2019

Как говорит Крокодилко, у вас есть зависимые таблицы с внешним ключом и опцией on delete cascade? Блокировка SSX запрещает вставки в дочернюю таблицу родительской таблицы, в которой была удалена строка.

См .: https://asktom.oracle.com/pls/apex/asktom.search?tag=deadlock-on-two-delete-statements

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...