본문 바로가기

db/oracle

ORA-00054: 자원이 사용 중이고 NOWAIT가 지정됨 (Resource Busy and NOWAIT Specified)

반응형

ORA-00054: 자원이 사용 중이고 NOWAIT가 지정됨 (Resource Busy and NOWAIT Specified)

 

ORA-00054 오류는 오라클 데이터베이스에서 발생하는 오류 중 하나로, "자원이 사용 중이고, NOWAIT가 지정되어 있습니다(resource busy and acquire with NOWAIT specified)" 또는 "제한 시간 초과(timeout expired)"라는 의미입니다. 이 오류는 현재 세션이 특정 리소스(주로 테이블이나 행)에 접근하려고 시도했지만, 다른 세션이 이미 해당 리소스를 잠그고 있기 때문에 즉시 접근할 수 없을 때 발생합니다. 특히, NOWAIT 옵션을 사용한 경우, 대기하지 않고 즉시 오류를 반환하며, WAIT n 옵션을 사용했을 때 지정된 시간(n 초) 내에 락을 획득하지 못하면 시간 초과로 오류가 발생합니다.

ORA-00054 오류의 주요 원인
  • 테이블 락(Table Lock) : 다른 세션이 테이블 전체에 락을 걸고 있는 경우, 해당 테이블에 접근하려는 모든 작업이 ORA-00054 오류를 발생시킬 수 있습니다. 이는 주로 TRUNCATE TABLE과 같은 DDL(Data Definition Language) 명령어나 장시간 실행되는 DML(Data Manipulation Language) 작업으로 인해 발생합니다.
  • 행 락(Row Lock) : 특정 행을 수정(UPDATE), 삭제(DELETE), 또는 SELECT FOR UPDATE 구문을 사용하여 락을 건 경우, 다른 세션이 해당 행에 접근하려고 하면 ORA-00054 오류가 발생할 수 있습니다.
  • 인덱스 락(Index Lock) : 인덱스에 대한 작업(예: 인덱스 재생성)이 진행 중일 때, 해당 인덱스를 사용하는 쿼리가 ORA-00054 오류를 발생시킬 수 있습니다.
  • NOWAIT 옵션 사용 : 쿼리나 DML 문에 NOWAIT 옵션을 명시적으로 지정한 경우, 락을 즉시 획득할 수 없으면 대기하지 않고 ORA-00054 오류를 반환합니다.
  • WAIT n 옵션 사용 : 쿼리나 DML 문에 WAIT n 옵션을 지정한 경우, n 초 내에 락을 획득하지 못하면 시간 초과로 ORA-00054 오류를 반환합니다.
ORA-00054 오류 해결 방법
  • ORA-00054 오류는 다른 세션이 리소스를 점유하고 있기 때문에 발생하는 오류이므로, 근본적인 해결책은 락을 해제하거나 락 경쟁을 줄이는 것입니다.

1. 대기 후 재시도 : 가장 간단한 해결 방법은 잠시 기다린 후 작업을 다시 시도하는 것입니다. 대부분의 경우, 락을 점유하고 있던 세션이 작업을 완료하면 락이 해제되어 정상적으로 작업을 수행할 수 있습니다.

 

2. 락을 잡고 있는 세션 확인 및 종료 (DBA 권한 필요) : 데이터베이스 관리자(DBA) 권한이 있는 경우, 락을 잡고 있는 세션을 확인하고 필요에 따라 해당 세션을 강제로 종료할 수 있습니다.

  • 락을 잡고 있는 객체 확인 
SELECT object_name
FROM v$locked_object lo, dba_objects do
WHERE lo.object_id = do.object_id;
  • 락을 잡고 있는 세션 확인
SELECT s.sid, s.serial#, s.username, s.status, l.lock_type, l.mode_held, l.mode_requested
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND l.type = 'TM' -- 테이블 락
AND l.mode_held > 1; -- 락이 걸린 상태 (1: None, 2: Row-S (SS), 3: Row-X (SX), 4: Share (S), 5: S/Row-X (SRX), 6: Exclusive (X))
  • 세션 강제 종료
ALTER SYSTEM KILL SESSION 'sid,serial#'; -- 예: ALTER SYSTEM KILL SESSION '123,456';


3. NOWAIT 또는 WAIT n 옵션 제거 또는 조정 : 쿼리나 DML 문에 NOWAIT 옵션을 사용하고 있다면, 해당 옵션을 제거하거나 WAIT n 옵션을 사용하여 적절한 대기 시간을 설정합니다. 예를 들어, SELECT ... FOR UPDATE NOWAIT 대신 SELECT ... FOR UPDATE WAIT 10과 같이 사용하면 10초 동안 대기 후 락을 획득하지 못하면 오류를 반환합니다.

 

4. 트랜잭션 관리 : 애플리케이션에서 트랜잭션을 명확하게 관리하여 락을 점유하는 시간을 최소화합니다. 트랜잭션이 불필요하게 길어지지 않도록 주의해야 합니다.

 

5. 작업 순서 조정 : 여러 테이블에 접근하는 경우, 모든 트랜잭션에서 동일한 순서로 테이블에 접근하도록 하여 교착 상태(Deadlock) 발생 가능성을 줄입니다.

 

6. 인덱스 재구성 시 주의 : 인덱스를 재구성하는 작업은 테이블에 장시간 락을 걸 수 있으므로, 시스템 부하가 적은 시간대에 수행하거나 온라인 인덱스 재구성 기능을 사용하는 것을 고려해야 합니다.

 

7. 애플리케이션 로직 개선 : 불필요한 락 획득을 최소화하고, 락 경쟁을 줄이는 방향으로 애플리케이션 로직을 개선합니다.

예시
-- ORA-00054 발생 가능성이 있는 쿼리
UPDATE EMP SET SAL = SAL * 1.1 WHERE DEPTNO = 10 NOWAIT;

-- 해결 방법 (대기 시간 설정)
UPDATE EMP SET SAL = SAL * 1.1 WHERE DEPTNO = 10 WAIT 5; -- 5초 동안 대기

 

※ ORA-00054 오류는 락 경쟁으로 인해 발생하는 오류이므로, 락을 해제하거나 락 경쟁을 줄이는 것이 핵심입니다. 위에서 설명한 해결 방법을 참고하여 상황에 맞는 적절한 조치를 취해야 합니다. 특히, DBA 권한이 있는 경우, 락을 잡고 있는 세션을 확인하고 관리하는 것이 중요하며, 애플리케이션 개발 단계에서 트랜잭션 관리와 락 사용에 주의를 기울여 오류 발생을 예방하는 것이 좋습니다.

반응형