enq : TX-row lock 경합 문제를 해결하는 방법은 무엇입니까? 0000000810EFA958

다음과 같은 상황이 있습니다.

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_STRING세션을 차단 sql_id.

어디서부터 시작해야합니까?

커밋 / 롤백이 누락 된 것으로 추측 할 수 있지만 응용 프로그램 개발자는 “모든 것이 정상이며 필요한 곳에 커밋을 작성했습니다”라고 말합니다.

도와주세요.



답변

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;


답변

당신은 행이 미리와 업데이트를 사용할 수 있는지 확인하여 행 잠금 경합을 피할 수 있습니다 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를 받게됩니다.


답변

보다 우아하고 안전한 업데이트 건너 뛰기 선택을 사용할 수 있습니다.


답변