Bagaimana cara memecahkan masalah enq: TX - pertikaian kunci baris?

9

Saya memiliki situasi berikut.

Saya punya RAC. Di kedua node ada kunci.

Di Node Pertama

    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

Memblokir info sesi

    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

Di Simpul Kedua

    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

Memblokir info sesi

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

Info Tambahan: Memblokir sesi 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;

Bagaimana saya memecahkan masalah ini?

Seperti yang Anda lihat, sesi pemblokiran tidak aktif tetapi masih terkunci.

Jika saya select v$sql_bind_capturetidak ada nilai untuk VALUE_STRINGsesi pemblokiran sql_id.

Dari mana memulainya?

Saya bisa menebak bahwa ada komit / kembalikan yang hilang tetapi pengembang aplikasi mengatakan "Saya memiliki segalanya ok, saya telah menulis komit di mana perlu"

Tolong bantu.

kupa
sumber

Jawaban:

6

Kueri v$transactionpada setiap node untuk melihat sesi yang tidak dikomit:

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
sumber
5

Anda dapat menghindari pertikaian kunci baris dengan memastikan bahwa baris tersebut tersedia untuk pembaruan terlebih dahulu dengan a SELECT FOR UPDATEdan salah satu WAIT Xatau NOWAIT, misalnya:

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;

Jika baris dikunci, Anda akan menerima ORA-00054 yang dalam banyak kasus lebih disukai daripada menunggu tidak terbatas.

Vincent Malgrat
sumber
0

Anda dapat menggunakan pilih untuk pembaruan lewati terkunci yang lebih elegan dan lebih aman

kamal qoshtom
sumber
Saya tidak cukup tahu tentang masalah untuk dapat mengetahui apakah jawaban Anda benar atau tidak. Namun, ini agak pendek - lihat yang lain. Jawaban di sini harus disertai dengan semacam perluasan dan mungkin tautan ke dokumentasi! Saya memiliki satu tautan ke petunjuk tentang cara menjawab pertanyaan oleh Jon Skeet (lebih dari 1 juta poin di StackExchange) - mungkin Anda ingin melihatnya dan mencoba mengikuti petunjuknya? ps selamat datang di forum! :-)
Vérace