Fehlerbehebung bei enq: TX - Zeilensperrkonflikten?

9

Ich habe die folgende Situation.

Ich habe RAC. Auf beiden Knoten befinden sich die Sperren.

Auf dem ersten Knoten

    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

Sitzungsinformationen blockieren

    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

Auf dem zweiten Knoten

    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

Sitzungsinformationen blockieren

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

Zusätzliche Informationen: Blockieren der Sitzung 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;

Wie behebe ich das?

Wie Sie sehen können, ist das Blockieren der Sitzung INAKTIV, aber immer noch gesperrt.

Wenn ich, select v$sql_bind_capturegibt es keinen Wert VALUE_STRINGfür das Blockieren der Sitzung sql_id.

Wo soll ich anfangen?

Ich kann mir vorstellen, dass Commit / Rollback fehlt, aber der Anwendungsentwickler sagt: "Ich habe alles in Ordnung, ich habe Commit geschrieben, wo es notwendig ist."

Bitte helfen Sie.

kupa
quelle

Antworten:

6

Abfrage v$transactionauf jedem Knoten, um nicht festgeschriebene Sitzungen anzuzeigen:

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;
Leigh Riffel
quelle
5

Sie können Konflikte mit Zeilensperren vermeiden, indem Sie sicherstellen, dass die Zeile vorab mit einem SELECT FOR UPDATEund entweder WAIT Xoder NOWAIT, z.

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;

Wenn die Zeile gesperrt ist, erhalten Sie einen ORA-00054, der in den meisten Fällen dem unbestimmten Warten vorzuziehen ist.

Vincent Malgrat
quelle
0

Sie können die Option für Update-Überspringen gesperrt verwenden, die eleganter und sicherer ist

Kamal Qoshtom
quelle
Ich weiß nicht genug über das Problem, um feststellen zu können, ob Ihre Antwort richtig ist oder nicht. Es ist jedoch etwas kurz - schauen Sie sich die anderen an. Die Antworten hier sollten von einer Art Erweiterung und möglicherweise Links zur Dokumentation begleitet werden! Ich habe einen Link zu einer Anleitung zur Beantwortung von Fragen von Jon Skeet (mehr als 1 Million Punkte bei StackExchange) - vielleicht möchten Sie sie sich ansehen und versuchen, den Hinweisen zu folgen? ps willkommen im forum! :-)
Vérace