Pourquoi ai-je cette erreur de base de données lorsque je mets à jour une table ?
ERREUR à la ligne 1 :
ORA-00054 : ressource occupée et acquisition avec spécification de NOWAIT ou expiration du délai
Pourquoi ai-je cette erreur de base de données lorsque je mets à jour une table ?
ERREUR à la ligne 1 :
ORA-00054 : ressource occupée et acquisition avec spécification de NOWAIT ou expiration du délai
Je rajouterais 'dans une autre session' à ça. Un scénario courant est que vous avez testé la mise à jour dans un outil, disons SQL Developer ou Toad, et que vous avez ensuite essayé de l'exécuter ailleurs alors que la première session détient toujours le verrou. Vous devez donc valider/annuler l'autre session avant de pouvoir exécuter à nouveau la mise à jour.
Il est très probable que ce soit une DML (insertion/suppression/mise à jour) plutôt qu'une requête. De plus, dans une autre session. Simplement parce que la personne qui demande semble être un débutant, la réponse peut être correcte. Mais vous ne pouvez PAS valider au nom d'autres utilisateurs dans un système de production.
Eh bien, ce qui m'a causé ce problème était dans Toad : Un collègue était dans la même table que moi lorsque je voulais supprimer une ligne, et donc je ne pouvais pas la supprimer. Lorsqu'il est passé à une autre table, j'ai pu supprimer des lignes. Cela pourrait peut-être aider quelqu'un. Mais ceci est seulement si vous travaillez avec Toad à l'intérieur des tables, et pas pour les requêtes.
À partir d'ici ORA-00054: ressource occupée et acquire avec NOWAIT spécifié
Vous pouvez également rechercher les informations sql, nom d'utilisateur, machine, port et accéder au processus réel qui détient la connexion
SELECT O.OBJECT_NAME, S.SID, S.SERIAL#, P.SPID, S.PROGRAM,S.USERNAME,
S.MACHINE,S.PORT , S.LOGON_TIME,SQ.SQL_FULLTEXT
FROM V$LOCKED_OBJECT L, DBA_OBJECTS O, V$SESSION S,
V$PROCESS P, V$SQL SQ
WHERE L.OBJECT_ID = O.OBJECT_ID
AND L.SESSION_ID = S.SID AND S.PADDR = P.ADDR
AND S.SQL_ADDRESS = SQ.ADDRESS;
Les verrous sont transitoires. donc si l'insertion arrive, vous validez immédiatement. cela ne s'affichera pas dans cette requête. vous pouvez encore rencontrer l'erreur si vous émettez le 'DDL'. pendant que la transaction est ouverte. consultez mon message ci-dessous. C'est vraiment facile à contourner.
Je rencontre le même problème que l'OP, mais je ne vois pas la table dont vous parlez (par exemple, select * from V$LOCKED_OBJECT renvoie ORA-00942 : table ou vue n'existe pas). Des idées ?
Veuillez tuer la session Oracle
Utilisez la requête ci-dessous pour vérifier les informations des sessions actives
SELECT
O.OBJECT_NAME,
S.SID,
S.SERIAL#,
P.SPID,
S.PROGRAM,
SQ.SQL_FULLTEXT,
S.LOGON_TIME
FROM
V$LOCKED_OBJECT L,
DBA_OBJECTS O,
V$SESSION S,
V$PROCESS P,
V$SQL SQ
WHERE
L.OBJECT_ID = O.OBJECT_ID
AND L.SESSION_ID = S.SID
AND S.PADDR = P.ADDR
AND S.SQL_ADDRESS = SQ.ADDRESS;
Tuer la session comme suit
alter system kill session 'SID,SERIAL#';
(Par exemple, alter system kill session '13,36543'
;)
Référence http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html
Devrait préciser cette réponse par les privilèges nécessaires. J'ai CONNECT
et RESOURCE
, mais pas ce dont cela a besoin, avec le compte que j'ai, et dit ORA-00942: table ou vue n'existe pas
. Tout le monde lisant ce fil n'aura pas le compte SYS
.
Si vous ajoutez la colonne de sélection 'S.OSUSER', vous saurez également quel utilisateur exécutait cette transaction et ce sera pratique si vous voulez vérifier avec l'utilisateur avant de tuer la session.
Si la session est suspendue, alors alter system kill session '13,36543'
expirera et la session ne mourra pas. Dans ce cas, voir: stackoverflow.com/a/24306610/587365
Il existe une solution très facile à ce problème.
Si vous exécutez une trace 10046 sur votre session (recherchez sur Google pour plus d'informations... trop long à expliquer). Vous verrez qu'avant toute opération DDL, Oracle effectue les étapes suivantes:
LOCK TABLE 'TABLE_NAME' NO WAIT
Donc, si une autre session a une transaction ouverte, vous obtenez une erreur. La solution est donc... roulement de tambour. Bloquez votre propre verrou avant le DDL et supprimez le 'NO WAIT'.
Note spéciale:
si vous divisez/supprimez des partitions, Oracle verrouille uniquement la partition. - donc vous pouvez simplement verrouiller la sous-partition de la partition.
Ainsi... Les étapes suivantes résolvent le problème.
Les instructions DML 'attendent' ou, comme les développeurs l'appellent, 'bloquent' tant que la table est verrouillée.
Je fais cela dans du code qui s'exécute à partir d'une tâche pour supprimer des partitions. Cela fonctionne bien. C'est dans une base de données qui insère constamment à un rythme de plusieurs centaines d'insertions par seconde. Aucune erreur.
Si vous vous posez la question. J'ai fait cela en 11g. Je l'ai également fait en 10g dans le passé.
Ok, ce n'est pas correct. en 11g, utilisez set_ddl_timeout, C'est seulement disponible en 11g. oracle effectue un commit avant de faire du DDL, donc il libère le verrou. En 11g, vous pouvez faire attendre votre DDL. Je le fais maintenant. Fonctionne bien.
Ceci est vraiment utile si vous obtenez l'ORA-00054 à partir des jobs de lot, mais je soupçonne que la plupart des personnes atterrissant ici (y compris l'OP, et moi) font du développement et ont laissé une session ouverte effectuant des insertions sur la même table qu'ils essaient de supprimer et recréer. KILL SESSION
est la bonne réponse pour ces personnes.
Cette erreur se produit lorsque la ressource est occupée. Vérifiez si vous avez des contraintes référentielles dans la requête. Ou même les tables que vous avez mentionnées dans la requête peuvent être occupées. Elles pourraient être engagées dans un autre travail qui sera certainement répertorié dans les résultats de la requête suivante :
SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'
Trouvez le SID,
SELECT * FROM V$OPEN_CURSOR WHERE SID = --l'identifiant
Dans de tels cas, les administrateurs de base de données sont responsables de fournir ces informations.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
23 votes
Il est généralement utile si vous publiez l'énoncé qui provoque l'erreur