Comment dépanner enq: TX - Conflit de verrouillage de ligne?


9

J'ai la situation suivante.

J'ai RAC. Sur les deux nœuds, il y a les verrous.

Sur le premier nœud

    SID EVENT                           USERNAME    BLOCKING_SESSION    ROW_WAIT_OBJ#   OBJECT_NAME LOCKWAIT            SQL_ID          STATUS
1   102 enq: TX - row lock contention   MYUSER      155                 136972          TABLE1V     0000000810EFA958    5f4bzdg49fdxq   ACTIVE
2   111 enq: TX - row lock contention   MYUSER      155                 136972          TABLE1V     0000000810EFAC98    5f4bzdg49fdxq   ACTIVE

Informations sur la session de blocage

    SID EVENT                       USERNAME    ROW_WAIT_OBJ#   OBJECT_NAME LOCKWAIT    SQL_ID          STATUS
1   155 SQL*Net message from client MYUSER      136971          MyTABLEIMAGES_IDPK      4hw85z8absbjc   INACTIVE

Sur le deuxième nœud

    SID EVENT                           USERNAME    BLOCKING_SESSION    ROW_WAIT_OBJ#   OBJECT_NAME   LOCKWAIT          SQL_ID          STATUS
1   65  enq: TX - row lock contention   MYUSER      155                 137033          FactTABLE1V   0000000810EF9B58  1mznc2z75ksdx   ACTIVE
2   111 enq: TX - row lock contention   MYUSER      155                 136972          TABLE1V       0000000810EF9818  5f4bzdg49fdxq   ACTIVE

Informations sur la session de blocage

    SID EVENT                       USERNAME    ROW_WAIT_OBJ#   OBJECT_NAME  SQL_ID  STATUS
1   155 SQL*Net message from client MYUSER      127176          MYTableLOG           INACTIVE

Informations supplémentaires: blocage de la session SQL_TEXT

create or replace procedure ACTIONProcedureDELETE
(
p_ID NUMBER
)
 is

 cursor oldval is select r.id,r.sessionstatus
  from MyTABLEIMAGES  r where r.idparent=p_ID;

begin
       update  actionmyTableblock r  set r.status='False' where  ID=p_ID;

   for oldvalItem in oldval loop

    if oldvalItem.Sessionstatus='True' then
      update MyTABLEIMAGES r set r.sessionstatus='False' where r.id=oldvalItem.Id;
    else
      update MyTABLEIMAGES r set r.sessionstatus='True' where r.id=oldvalItem.Id;
    end if;
  end loop;

end ACTIONProcedureDELETE;

Comment puis-je résoudre ce problème?

Comme vous pouvez le voir, la session de blocage est INACTIVE mais toujours verrouillable.

Si je n'ai select v$sql_bind_captureaucune valeur pour la VALUE_STRINGsession de blocage sql_id.

Par où commencer?

Je peux deviner qu'il n'y a pas de commit / rollback mais le développeur de l'application dit "J'ai tout ok, j'ai écrit un commit là où c'est nécessaire"

Veuillez aider.

Réponses:


6

Recherchez v$transactionsur chaque nœud pour voir les sessions non validées:

SELECT t.start_time, s.sid, s.serial#, s.username, s.status,s.schemaname, s.osuser
   , s.process, s.machine, s.terminal, s.program, s.module
   , to_char(s.logon_time,'DD/MON/YY HH24:MI:SS') logon_time
FROM v$transaction t, v$session s
WHERE s.saddr = t.ses_addr
ORDER BY start_time;

5

Vous pouvez éviter les conflits de verrouillage de ligne en vous assurant que la ligne est disponible pour la mise à jour au préalable avec un SELECT FOR UPDATEet soit WAIT Xou NOWAIT, par exemple:

create or replace procedure ACTIONProcedureDELETE (p_ID NUMBER)
 is

 cursor oldval is select r.id,r.sessionstatus
  from MyTABLEIMAGES  r where r.idparent=p_ID FOR UPDATE NOWAIT;

 l_id NUMBER;

begin
   select id into l_id from actionmyTableblock where ID=p_ID 
      FOR UPDATE of status NOWAIT;

   update  actionmyTableblock r  set r.status='False' where  ID=p_ID;

   for oldvalItem in oldval loop

    if oldvalItem.Sessionstatus='True' then
      update MyTABLEIMAGES r set r.sessionstatus='False' where r.id=oldvalItem.Id;
    else
      update MyTABLEIMAGES r set r.sessionstatus='True' where r.id=oldvalItem.Id;
    end if;
  end loop;

end ACTIONProcedureDELETE;

Si la ligne est verrouillée, vous recevrez un ORA-00054 qui est dans la plupart des cas préférable à une attente indéfinie.


0

vous pouvez utiliser le sélecteur pour la mise à jour, verrouillé, ce qui est plus élégant et plus sûr


Je ne connais pas assez le problème pour pouvoir dire si votre réponse est correcte ou non. Cependant, c'est un peu court - jetez un œil aux autres. Les réponses ici devraient être accompagnées d'une explication quelconque et éventuellement de liens vers la documentation! J'ai un lien vers un guide pratique pour répondre aux questions de Jon Skeet (plus de 1 million de points sur StackExchange) - peut-être aimeriez-vous le regarder et essayer de suivre ses conseils? ps bienvenue sur le forum! :-)
Vérace
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.