วิธีแก้ปัญหา enq: TX - การช่วงชิงล็อกการล็อกแถว


9

ฉันมีสถานการณ์ต่อไปนี้

ฉันมี RAC บนโหนดทั้งสองมีการล็อคอยู่

บนโหนดแรก

    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

การปิดกั้นข้อมูลเซสชั่น

    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

บนโหนดที่สอง

    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

การปิดกั้นข้อมูลเซสชั่น

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

ข้อมูลเพิ่มเติม: การปิดกั้นเซสชัน 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;

ฉันจะแก้ไขปัญหานี้ได้อย่างไร

ตามที่คุณเห็นการบล็อคเซสชันไม่ทำงาน แต่ยังคงล็อคอยู่

ถ้าฉันselect v$sql_bind_captureมีค่าไม่มีสำหรับการปิดกั้นเซสชั่นVALUE_STRINGsql_id

จากที่จะเริ่ม?

ฉันสามารถเดาได้ว่าไม่มีคอมมิชชัน / ย้อนกลับ แต่ผู้พัฒนาแอปพลิเคชันกล่าวว่า "ฉันมีทุกอย่างโอเคฉันได้เขียนคอมมิทที่จำเป็น"

กรุณาช่วย.

คำตอบ:


6

เคียวรีv$transactionบนแต่ละโหนดเพื่อดูเซสชันที่ไม่มีข้อผูกมัด:

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

คุณสามารถหลีกเลี่ยงการช่วงชิงการล็อกแถวโดยตรวจสอบให้แน่ใจว่าแถวนั้นพร้อมสำหรับการอัปเดตล่วงหน้าด้วย a SELECT FOR UPDATEและอย่างใดอย่างหนึ่งWAIT XหรือNOWAITเช่น:

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;

หากแถวถูกล็อคคุณจะได้รับ ORA-00054 ซึ่งโดยส่วนใหญ่แล้วจะดีกว่าการรอแบบไม่ จำกัด


0

คุณสามารถใช้ตัวเลือกสำหรับการข้ามการล็อคที่อัปเดตซึ่งสวยงามและปลอดภัยกว่า


ฉันไม่รู้เกี่ยวกับปัญหาเพียงพอที่จะบอกได้ว่าคำตอบของคุณถูกต้องหรือไม่ อย่างไรก็ตามมันสั้นไปหน่อยลองดูที่คนอื่น คำตอบที่นี่ควรมีการอธิบายบางอย่างและอาจเชื่อมโยงไปยังเอกสาร! ฉันมีลิงก์ไปยังวิธีการตอบคำถามโดย Jon Skeet (มากกว่า 1 ล้านคะแนนใน StackExchange) - บางทีคุณอาจต้องการดูและลองทำตามคำแนะนำของมัน? ps ยินดีต้อนรับสู่ฟอรัม! :-)
Vérace
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.