2026년 10월 01일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-24003 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-24003 QUEUE already exists 는?
ORA-24003 에러는 Oracle Advanced Queuing(AQ) 환경에서 이미 존재하는 큐(Queue)를 동일한 이름으로 다시 생성하려 할 때 발생하는 에러입니다. Oracle의 DBMS_AQADM 패키지를 사용하여 큐를 생성할 때, 해당 스키마 내에 동일한 이름의 큐가 이미 존재한다면 Oracle은 이 에러를 반환하며 작업을 중단합니다. 특히 운영 환경에서 배포 스크립트를 반복 실행하거나, 개발 환경과 운영 환경 사이의 오브젝트 동기화 과정에서 자주 마주치는 에러입니다.
주요 발생 원인
1. 이미 존재하는 큐를 중복 생성 시도
가장 흔한 원인으로, 동일한 배포 스크립트를 두 번 이상 실행하거나 큐의 존재 여부를 사전에 확인하지 않고 DBMS_AQADM.CREATE_QUEUE 프로시저를 호출할 때 발생합니다. 특히 CI/CD 파이프라인에서 멱등성(Idempotency)을 고려하지 않은 스크립트가 반복 실행될 경우, 운영 환경에서 예기치 않은 에러로 이어질 수 있습니다.
2. 큐 삭제(DROP) 없이 큐 테이블 재생성 또는 재구성
큐 테이블(QUEUE TABLE)을 삭제하고 재생성하는 과정에서 큐 자체는 삭제되지 않은 상태로 남아 있을 때 발생합니다. Oracle AQ 구조상 큐 테이블과 큐는 별개의 오브젝트이므로, 큐 테이블만 삭제하고 다시 큐를 생성하려 하면 내부 메타데이터가 충돌하여 이 에러가 발생할 수 있습니다. DBA 또는 개발자가 AQ 오브젝트 간의 의존 관계를 정확히 이해하지 못한 경우에 자주 발생합니다.
3. 다른 스키마 또는 동일 스키마 내 이름 충돌
동일한 데이터베이스 내에서 큐 이름이 스키마 레벨에서 충돌하는 경우로, 특히 여러 팀이 동시에 AQ 오브젝트를 관리하거나, 테스트 환경의 스크립트를 운영 환경에 그대로 적용할 때 발생합니다. 큐 이름이 이미 다른 애플리케이션 모듈에 의해 선점되어 있는 상황을 인지하지 못한 채 생성을 시도하면 이 에러가 나타납니다.
해결 방법
해결책 1: 큐 존재 여부 사전 확인 후 조건부 생성
큐를 생성하기 전에 DBA_QUEUES 또는 USER_QUEUES 뷰를 조회하여 해당 큐가 이미 존재하는지 확인하고, 존재하지 않을 때만 생성하는 방식으로 스크립트를 멱등성 있게 작성합니다.
-- 큐 존재 여부 확인
SELECT name, queue_type, enqueue_enabled, dequeue_enabled
FROM user_queues
WHERE name = 'MY_ORDER_QUEUE';
-- PL/SQL을 활용한 조건부 큐 생성 (멱등성 보장)
DECLARE
v_count NUMBER := 0;
BEGIN
-- 큐 테이블 존재 여부 확인
SELECT COUNT(*)
INTO v_count
FROM user_queue_tables
WHERE queue_table = 'MY_ORDER_QUEUE_TABLE';
IF v_count = 0 THEN
DBMS_AQADM.CREATE_QUEUE_TABLE(
queue_table => 'MY_ORDER_QUEUE_TABLE',
queue_payload_type => 'SYS.AQ$_JMS_TEXT_MESSAGE'
);
DBMS_OUTPUT.PUT_LINE('Queue Table created successfully.');
ELSE
DBMS_OUTPUT.PUT_LINE('Queue Table already exists. Skipping creation.');
END IF;
-- 큐 존재 여부 확인
SELECT COUNT(*)
INTO v_count
FROM user_queues
WHERE name = 'MY_ORDER_QUEUE';
IF v_count = 0 THEN
DBMS_AQADM.CREATE_QUEUE(
queue_name => 'MY_ORDER_QUEUE',
queue_table => 'MY_ORDER_QUEUE_TABLE'
);
DBMS_AQADM.START_QUEUE(queue_name => 'MY_ORDER_QUEUE');
DBMS_OUTPUT.PUT_LINE('Queue created and started successfully.');
ELSE
DBMS_OUTPUT.PUT_LINE('Queue already exists. Skipping creation.');
END IF;
END;
/
해결책 2: 기존 큐를 정상적으로 삭제한 후 재생성
기존 큐를 완전히 제거하고 새로 생성해야 하는 경우, 반드시 큐 중지 → 큐 삭제 → 큐 테이블 삭제 순서를 따라야 합니다.
-- Step 1: 큐 중지 (Enqueue/Dequeue 비활성화)
BEGIN
DBMS_AQADM.STOP_QUEUE(
queue_name => 'MY_ORDER_QUEUE',
enqueue => TRUE,
dequeue => TRUE,
wait => TRUE -- 현재 처리 중인 메시지 완료 대기
);
END;
/
-- Step 2: 큐 삭제
BEGIN
DBMS_AQADM.DROP_QUEUE(
queue_name => 'MY_ORDER_QUEUE'
);
END;
/
-- Step 3: 큐 테이블 삭제 (FORCE 옵션으로 종속 큐 강제 삭제)
BEGIN
DBMS_AQADM.DROP_QUEUE_TABLE(
queue_table => 'MY_ORDER_QUEUE_TABLE',
force => TRUE
);
END;
/
-- Step 4: 큐 테이블 재생성
BEGIN
DBMS_AQADM.CREATE_QUEUE_TABLE(
queue_table => 'MY_ORDER_QUEUE_TABLE',
queue_payload_type => 'SYS.AQ$_JMS_TEXT_MESSAGE',
sort_list => 'PRIORITY,ENQ_TIME',
multiple_consumers => FALSE,
compatible => '10.0'
);
END;
/
-- Step 5: 큐 재생성 및 시작
BEGIN
DBMS_AQADM.CREATE_QUEUE(
queue_name => 'MY_ORDER_QUEUE',
queue_table => 'MY_ORDER_QUEUE_TABLE',
queue_type => DBMS_AQADM.NORMAL_QUEUE,
max_retries => 5,
retry_delay => 60,
retention_time => 0
);
DBMS_AQADM.START_QUEUE(
queue_name => 'MY_ORDER_QUEUE',
enqueue => TRUE,
dequeue => TRUE
);
END;
/
해결책 3: 현재 존재하는 모든 큐 및 큐 테이블 목록 조회
에러 발생 시 현재 데이터베이스 내의 AQ 오브젝트 현황을 파악하는 것이 우선입니다.
-- 현재 사용자 스키마의 모든 큐 조회
SELECT
name AS queue_name,
queue_table AS queue_table,
queue_type AS queue_type,
enqueue_enabled AS enq_enabled,
dequeue_enabled AS deq_enabled,
retention AS retention_time,
user_comment AS comments
FROM user_queues
ORDER BY name;
-- 현재 사용자 스키마의 모든 큐 테이블 조회
SELECT
queue_table,
type,
object_type,
recipients,
compatible
FROM user_queue_tables
ORDER BY queue_table;
-- DBA 권한으로 전체 스키마 큐 조회 (DBA 전용)
SELECT
owner,
name,
queue_table,
queue_type,
enqueue_enabled,
dequeue_enabled
FROM dba_queues
WHERE owner NOT IN ('SYS', 'SYSTEM')
ORDER BY owner, name;
예방 방법
1. 배포 스크립트에 반드시 멱등성(Idempotency) 로직 적용
모든 AQ 관련 배포 스크립트는 실행 전 오브젝트 존재 여부를 확인하는 조건부 로직을 포함해야 합니다. 단순히 CREATE_QUEUE를 호출하는 것이 아니라, 앞서 해결책 1에서 소개한 것처럼 user_queues, user_queue_tables 뷰를 조회한 후 존재하지 않을 때만 생성하도록 표준화된 템플릿을 팀 내에서 공유하고 적용해야 합니다. 이 접근 방식은 CI/CD 환경에서 특히 중요하며, 실수로 인한 에러 발생을 근본적으로 차단합니다.
2. AQ 오브젝트 변경 이력 및 의존성 문서화
운영 환경에서 관리되는 모든 큐와 큐 테이블의 생성/삭제/변경 이력을 형상 관리 시스템(Git 등)에 반드시 기록해야 합니다. 각 큐가 어떤 애플리케이션 모듈에서 사용되는지, 소비자(Subscriber)가 누구인지, 메시지 보존 기간은 얼마인지 등의 메타 정보를 문서화해 두면 중복 생성이나 실수로 인한 삭제를 방지할 수 있습니다. 특히 멀티 팀 환경에서는 큐 이름 명명 규칙(Naming Convention)을 팀 간에 합의하고 표준화하는 것이 필수적입니다.
관련 에러
- ORA-24001:
QUEUE TABLE already exists— 큐 테이블이 이미 존재할 때 발생하는 에러로, ORA-24003과 함께 자주 마주칩니다. 큐 테이블 생성 전에도 동일한 멱등성 로직을 적용해야 합니다. - ORA-24002:
QUEUE TABLE does not exist— 큐를 생성하려는 큐 테이블 자체가 존재하지 않을 때 발생합니다. 큐 생성 전 큐 테이블이 먼저 준비되어 있는지 확인이 필요합니다. - ORA-24010:
QUEUE does not exist— 이미 삭제되었거나 존재하지 않는 큐에 대해START_QUEUE,STOP_QUEUE,DROP_QUEUE등을 호출할 때 발생합니다. - ORA-24005:
Must use DBMS_AQADM.DROP_QUEUE_TABLE to drop queue tables— 큐 테이블을 일반DROP TABLE구문으로 삭제하려 할 때 발생하며, 반드시DBMS_AQADM.DROP_QUEUE_TABLE을 사용해야 함을 알려줍니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.