2026년 09월 30일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-24001 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-24001 cannot create QUEUE_TABLE, already exists 는?
ORA-24001 에러는 Oracle Advanced Queuing(AQ) 기능을 사용할 때 이미 존재하는 큐 테이블(Queue Table)을 다시 생성하려고 시도할 때 발생합니다. DBMS_AQADM.CREATE_QUEUE_TABLE 프로시저를 호출했을 때, 동일한 이름의 큐 테이블이 해당 스키마에 이미 존재한다면 Oracle은 이 에러를 반환하며 작업을 중단합니다. 주로 배포 스크립트를 반복 실행하거나, 개발 환경에서 초기화 작업 없이 동일한 설정 스크립트를 재실행할 때 자주 마주치는 에러입니다.
주요 발생 원인
1. 배포 스크립트의 중복 실행
CI/CD 파이프라인이나 수동 배포 과정에서 초기화(Drop) 단계 없이 동일한 생성 스크립트를 두 번 이상 실행하는 경우가 가장 흔한 원인입니다. 개발자가 이미 운영 환경에 큐 테이블이 생성되어 있다는 사실을 인지하지 못하고 스크립트를 재실행하거나, 자동화된 배포 툴이 멱등성(Idempotency) 없이 설계된 경우에 발생합니다.
2. 동일 스키마 내 큐 테이블 이름 충돌
여러 개발자 또는 여러 애플리케이션 모듈이 동일한 스키마를 공유할 때, 서로 다른 목적으로 같은 이름의 큐 테이블을 생성하려고 시도하면 에러가 발생합니다. 특히 공통 유틸리티 스키마나 통합 테스트 환경에서 협업 시 이름 규칙이 명확히 정해지지 않으면 이런 충돌이 빈번하게 발생합니다.
3. 불완전한 큐 삭제 후 재생성 시도
큐(Queue)는 삭제했지만 큐 테이블(Queue Table)은 삭제하지 않은 상태에서 동일한 큐 테이블을 다시 생성하려 할 때 에러가 발생합니다. DBMS_AQADM.DROP_QUEUE로 큐만 제거하고 DBMS_AQADM.DROP_QUEUE_TABLE을 실행하지 않으면, 테이블은 데이터 딕셔너리에 여전히 남아 있어 이후 생성 시 충돌이 일어납니다.
해결 방법
원인 1: 배포 스크립트 중복 실행 해결
생성 전에 큐 테이블의 존재 여부를 먼저 확인하고, 없을 때만 생성하는 방어적 스크립트를 작성합니다.
-- 큐 테이블 존재 여부 확인 후 조건부 생성
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_count
FROM user_queue_tables
WHERE queue_table = 'MY_QUEUE_TABLE';
IF v_count = 0 THEN
DBMS_AQADM.CREATE_QUEUE_TABLE(
queue_table => 'MY_QUEUE_TABLE',
queue_payload_type => 'SYS.AQ$_JMS_TEXT_MESSAGE',
comment => '주문 처리 큐 테이블'
);
DBMS_OUTPUT.PUT_LINE('Queue Table 생성 완료.');
ELSE
DBMS_OUTPUT.PUT_LINE('Queue Table 이미 존재함. 생성 건너뜀.');
END IF;
END;
/
원인 2: 큐 테이블 이름 충돌 해결
현재 스키마에 존재하는 모든 큐 테이블을 먼저 조회하여 이름 충돌 여부를 확인합니다.
-- 현재 스키마의 큐 테이블 목록 조회
SELECT queue_table,
type,
object_type,
recipients,
compatible
FROM user_queue_tables
ORDER BY queue_table;
-- DBA 권한이 있을 경우 전체 스키마 조회
SELECT owner,
queue_table,
type,
object_type
FROM dba_queue_tables
WHERE owner = 'APP_SCHEMA'
ORDER BY owner, queue_table;
충돌이 확인된 경우, 기존 테이블을 삭제 후 재생성합니다.
-- 안전한 큐 및 큐 테이블 삭제 후 재생성 절차
BEGIN
-- Step 1: 큐 정지 (STOP)
DBMS_AQADM.STOP_QUEUE(queue_name => 'MY_QUEUE');
-- Step 2: 큐 삭제
DBMS_AQADM.DROP_QUEUE(queue_name => 'MY_QUEUE');
-- Step 3: 큐 테이블 삭제 (force => TRUE 로 연관 큐 강제 삭제)
DBMS_AQADM.DROP_QUEUE_TABLE(
queue_table => 'MY_QUEUE_TABLE',
force => TRUE
);
-- Step 4: 큐 테이블 재생성
DBMS_AQADM.CREATE_QUEUE_TABLE(
queue_table => 'MY_QUEUE_TABLE',
queue_payload_type => 'RAW'
);
-- Step 5: 큐 재생성
DBMS_AQADM.CREATE_QUEUE(
queue_name => 'MY_QUEUE',
queue_table => 'MY_QUEUE_TABLE'
);
-- Step 6: 큐 시작
DBMS_AQADM.START_QUEUE(queue_name => 'MY_QUEUE');
DBMS_OUTPUT.PUT_LINE('큐 및 큐 테이블 재생성 완료.');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('오류 발생: ' || SQLERRM);
RAISE;
END;
/
원인 3: 불완전한 큐 삭제 후 재생성 해결
큐 테이블에 연결된 큐가 남아있는지 확인하고 올바른 순서로 정리합니다.
-- 특정 큐 테이블에 속한 큐 목록 확인
SELECT name AS queue_name,
queue_type,
enqueue_enabled,
dequeue_enabled
FROM user_queues
WHERE queue_table = 'MY_QUEUE_TABLE';
-- 남아있는 큐를 모두 정리한 후 큐 테이블 삭제
BEGIN
-- force => TRUE 옵션으로 연관 큐 포함 강제 삭제
DBMS_AQADM.DROP_QUEUE_TABLE(
queue_table => 'MY_QUEUE_TABLE',
force => TRUE
);
DBMS_OUTPUT.PUT_LINE('큐 테이블 삭제 성공.');
END;
/
예방 방법
1. 멱등성(Idempotent) 기반의 배포 스크립트 설계
모든 AQ 관련 배포 스크립트는 반복 실행해도 오류가 발생하지 않도록 IF NOT EXISTS 패턴(Oracle의 경우 딕셔너리 조회 방식)을 반드시 적용해야 합니다. user_queue_tables 또는 dba_queue_tables 뷰를 활용하여 생성 전 항상 존재 여부를 점검하는 표준 템플릿을 팀 내 공유하고 코드 리뷰 체크리스트에 포함시키는 것을 권장합니다.
2. 큐 객체 네이밍 컨벤션 및 소유권 관리
큐 테이블 이름에 애플리케이션 모듈명, 환경 구분자(DEV/STG/PRD), 버전 등을 포함한 명확한 네이밍 컨벤션을 정의하고, 각 큐 테이블의 소유권을 문서화합니다. 예를 들어 {APP}_{MODULE}_QT_{ENV} 형식(예: ORD_PAY_QT_PRD)을 사용하면 이름 충돌을 사전에 방지할 수 있습니다. 또한 전용 AQ 관리 스키마를 분리하여 공용 스키마에서의 혼용을 방지하는 것이 좋습니다.
관련 에러
- ORA-24002:
QUEUE_TABLE does not exist— 존재하지 않는 큐 테이블에 접근하거나 조작하려 할 때 발생합니다. ORA-24001과 반대 상황입니다. - ORA-24010:
QUEUE does not exist— 큐 테이블은 존재하지만 해당 큐가 없을 때 발생합니다. - ORA-24011:
cannot drop QUEUE_TABLE, queues exist— 큐 테이블을 삭제하기 전에 연결된 큐를 먼저 삭제하지 않았을 때 발생하며,force => TRUE옵션으로 해결 가능합니다. - ORA-24034:
application already subscribed to queue— 동일 큐에 중복 구독자를 등록하려 할 때 발생하며, AQ 설정 스크립트 중복 실행 시 함께 나타날 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.