다음과 같은 상황이 있습니다.
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를 받게됩니다.
답변
보다 우아하고 안전한 업데이트 건너 뛰기 선택을 사용할 수 있습니다.