J'ai souvent cette erreur "ora-00060 détectée en attendant la ressource" souvent dans mon application lorsque plusieurs utilisateurs utilisent l'application. J'ai le fichier de trace de l'administrateur Oracle, mais j'ai besoin d'aide pour le lire. Vous trouverez ci-dessous des bits de données du fichier de trace, qui, je l'espère, aideraient à localiser la cause.
*** 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
===================================================
J'apprécierais que quelqu'un me dise ce que dit le "Deadlock graph ::". De plus, les lignes attendues dans la section ne contiennent aucune ligne.
J'ai également lu dans certains blogs que la section "sqltxt" du fichier de trace peut suggérer la cause. Voici la requête que je vois dans cette section.
select /*+ all_rows */ count(1) from "USERS"."EMPLOYEE_SALARY" where EMPSAL_EMP_ID=:1
La table employee_salary a une contrainte de clé étrangère sur la colonne EMPSAL_EMP_ID.
Le conseil sql indique "all_rows", donc cela signifie-t-il que cette table obtient le verrouillage au niveau de la table lors de la suppression des enregistrements de la table des employés? je n'ai pas d'index sur la colonne de clé étrangère actuellement. L'ajout d'un index sur cette colonne serait-il utile?
Veuillez poster, au cas où plus d'informations seraient nécessaires.
Merci
Tout d'abord, l'instruction select
ne verrouille jamais rien dans Oracle, utilise uniquement la dernière version cohérente disponible des données. Ce n'est pas un cas pour select ... for update
qui verrouille les données comme update
depuis Oracle 9i, mais il n'y a pas for update
clause dans la requête de la question.
Resource Name process session holds waits process session holds waits
TM-000151a2-00000000 210 72 SX SSX 208 24 SX SSX
La session n ° 72 contient un verrou de niveau table (TM) avec le type "Row Exclusive" (SX) et souhaite acquérir un verrou "Partager Row Exclusive" (SSX) sur la même table. Cette session bloquée par la session # 24 qui détient déjà un verrou de niveau table d'un même type (SX) et attend que le verrou SSX soit disponible.
Resource Name process session holds waits process session holds waits
TM-000151a2-00000000 208 24 SX SSX 210 72 SX SSX
Cette (deuxième ligne) montre exactement la même situation, mais dans la direction opposée: la session # 24 attend que le verrouillage SSX soit disponible, mais bloqué par la session # 72 qui détient déjà le verrouillage SX sur la même table.
Ainsi, les sessions # 24 et session # 72 se bloquent: un blocage se produit.
Les deux types de verrous (SX et SSX) sont des verrous de niveau table.
Pour comprendre la situation, je recommande de lire cet article par Franck Pachot.
Vous trouverez ci-dessous la citation de cet article, qui concerne directement votre situation (notez que les abréviations SSX et SRX sont équivalentes):
L'intégrité référentielle acquiert également des verrous TM. Par exemple, le problème courant avec les clés étrangères non indexées conduit à des verrous S sur la table enfant lorsque vous effectuez une suppression ou une mise à jour sur la clé, sur la table parent. En effet, sans index, Oracle n'a pas de ressource de niveau inférieur unique à verrouiller afin d'empêcher une insertion simultanée pouvant violer l'intégrité référentielle.
Lorsque les colonnes de clé étrangère sont les colonnes de tête d'un index normal, la première entrée d'index avec la valeur parent peut être utilisée comme une ressource unique et verrouillée avec un verrou TX au niveau de la ligne.
Et si l'intégrité référentielle a une cascade de suppression? En plus du mode S, il est prévu de mettre à jour les lignes de la table enfant, comme avec le mode Row X (RX). C'est là que la ligne de partage exclusive (SRX) se produit: S + RX = SRX.
Ainsi, la variante la plus probable est que la session # 72 et la session # 24 suppriment en même temps certaines lignes de la table EMPLOYEE
, et il y a on delete cascade
contrainte pour EMPSAL_EMP_ID
en conjonction avec l'absence d'index sur EMPLOYEE_SALARY
table dans laquelle EMPSAL_EMP_ID
colonne répertoriée en premier.