Поиск причины ошибки взаимоблокировки из файла трассировки oracle

Я получаю эту частоту "ora-00060 тупик, обнаруженный при ожидании ресурса", часто в моем приложении, когда несколько пользователей используют приложение. У меня есть файл трассировки из Admin, но вам нужна помощь в его чтении. Ниже приведены биты данных из файла трассировки, которые, я надеюсь, помогут найти причину.

*** 2013-06-25 09:37:35.324
DEADLOCK DETECTED ( ORA-00060 )

[Transaction Deadlock]

The following deadlock is not an ORACLE error. It is a deadlock due 
to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:

Deadlock graph:
                   ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       210      72    SX   SSX      208      24    SX   SSX
TM-000151a2-00000000       208      24    SX   SSX      210      72    SX   SSX

session 72: DID 0001-00D2-000000C6  session 24: DID 0001-00D0-00000043 
session 24: DID 0001-00D0-00000043  session 72: DID 0001-00D2-000000C6 

Rows waited on:
 Session 72: no row
 Session 24: no row

----- Information for the OTHER waiting sessions -----
Session 24:
 sid: 24 ser: 45245 audsid: 31660323 user: 90/USER
  flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
  flags2: (0x40009) -/-/INC
 pid: 208 O/S info: user: zgrid, term: UNKNOWN, ospid: 2439
   image: [email protected]
 client details:
   O/S info: user: , term: , ospid: 1234
   machine: xyz.local program: 
 current SQL:
  delete from EMPLOYEE where EMP_ID=:1

 ----- End of information for the OTHER waiting sessions -----

Information for THIS session:

 ----- Current SQL Statement for this session (sql_id=dyfg1wd8xa9qt) -----
 delete from EMPLOYEE where EMP_ID=:1
===================================================

Я был бы признателен, если кто-нибудь скажет мне, что говорит "Deadlock graph::". Также строки, ожидающие в разделе, не содержат строк.

Я также читал в некоторых блогах, что раздел "sqltxt" из файла трассировки может предложить причину. Ниже приведен запрос, который я вижу в этом разделе.

 select /*+ all_rows */ count(1) from "USERS"."EMPLOYEE_SALARY" where EMPSAL_EMP_ID=:1

В таблице employee_salary есть ограничение постороннего ключа в столбце EMPSAL_EMP_ID.

В подсказке sql говорится "all_rows", значит ли это, что эта таблица получает блокировку на уровне таблицы при удалении записей из таблицы employee? В настоящее время у меня нет индекса в столбце внешнего ключа. Добавил бы индекс в эту помощь столбца?

Прошу прощения, если вам нужна дополнительная информация.

Спасибо

Ответы

Ответ 1

Прежде всего, оператор select никогда не блокирует что-либо в Oracle, просто использует последнюю доступную согласованную версию данных. Это не случай для select ... for update, который блокирует данные типа update с Oracle 9i, но в вопросе из вопроса нет предложения for update.

Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       210      72    SX   SSX      208      24    SX   SSX

Сессия № 72 содержит блокировку на уровне таблицы (TM) с типом "Row Exclusive" (SX) и хочет приобрести блокировку "Share Row Exclusive" (SSX) в той же таблице. Этот сеанс заблокирован сеансом № 24, который уже содержит блокировку на уровне таблицы одного и того же типа (SX) и ждет, пока блокировка SSX будет доступна.

Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       208      24    SX   SSX      210      72    SX   SSX

Эта (вторая строка) демонстрирует точно такую ​​же ситуацию, но в противоположном направлении: сеанс № 24 ожидает, что блокировка SSX станет доступной, но заблокирована сеансом № 72, который уже удерживает блокировку SX в одной таблице.

Итак, сеансы # 24 и сеанс № 72 блокируют друг друга: происходит взаимоблокировка.

Оба типа блокировки (SX и SSX) являются блокировками на уровне таблицы.
Чтобы понять ситуацию, я рекомендую прочитать эту статью от Franck Pachot.

Ниже приведена цитата из этой статьи, которая имеет прямое отношение к вашей ситуации (обратите внимание, что аббревиатуры SSX и SRX эквивалентны):

Ссылочная целостность также получает блокировки TM. Например, общий проблема с неиндексированными внешними ключами приводит к блокировке S на дочернем столе, когда вы производите удаление или обновление ключа в родительской таблице. Это поскольку без индекса Oracle не имеет единого ресурса нижнего уровня для блокировки, чтобы предотвратить одновременную вставку, которая может нарушить ссылочная целостность.
Когда столбцы внешнего ключа являются ведущими столбцы в регулярном индексе, то первая запись индекса с родительским значение может использоваться как один ресурс и заблокирован с помощью TX блокировки.
И что, если ссылочная целостность имеет на каскаде удаления? В дополнение к режиму S, есть намерение обновить строки в дочерний стол, как и в режиме Row X (RX). Это где доля строк (SRX): S + RX = SRX.

Таким образом, наиболее вероятным вариантом является то, что сеанС# 72 и сеанс 24 одновременно удаляют несколько строк в таблице EMPLOYEE, а ограничение on delete cascade для EMPSAL_EMP_ID в связи с отсутствием индекса на EMPLOYEE_SALARY таблица, в которой столбец EMPSAL_EMP_ID указан первым.