2026년 10월 02일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-24034 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-24034 application is already a subscriber to queue 는?
ORA-24034 에러는 Oracle Advanced Queuing(AQ) 환경에서 특정 애플리케이션 또는 구독자(subscriber)가 이미 해당 큐(Queue)에 등록되어 있는 상태에서 동일한 구독자를 다시 추가하려고 할 때 발생합니다. Oracle AQ는 동일한 큐에 동일한 이름의 구독자를 중복으로 허용하지 않기 때문에, 이미 존재하는 구독자를 재등록하는 시도를 차단하고 이 에러를 발생시킵니다. 주로 애플리케이션 배포 스크립트나 초기화 코드가 멱등성(idempotency) 없이 구독자를 등록할 때, 혹은 중복 실행 시 나타나는 전형적인 문제입니다.
주요 발생 원인
1. 구독자 등록 스크립트의 중복 실행
애플리케이션 배포 또는 초기화 스크립트에 DBMS_AQADM.ADD_SUBSCRIBER 호출이 포함된 경우, 해당 스크립트를 두 번 이상 실행하면 이미 등록된 구독자를 또다시 추가하려 하여 ORA-24034가 발생합니다. 특히 CI/CD 파이프라인이나 자동화된 배포 환경에서 스크립트 실행 이력을 관리하지 않으면 이 문제가 빈번하게 발생합니다. 실행 전 구독자 존재 여부를 확인하는 로직이 없는 것이 근본 원인입니다.
2. 애플리케이션 코드에서 구독자 등록 시 예외 처리 부재
일부 애플리케이션은 시작(startup) 단계에서 큐 구독자를 동적으로 등록하는 로직을 포함하고 있습니다. 애플리케이션이 재시작되거나 다중 인스턴스(multi-instance)로 운영될 경우, 각 인스턴스가 동일한 구독자 이름으로 등록을 시도하여 두 번째 이후 시도부터 ORA-24034가 발생합니다. 이미 등록된 경우를 고려한 예외 처리(EXCEPTION WHEN OTHERS) 또는 사전 확인 로직이 없으면 애플리케이션이 비정상 종료될 수 있습니다.
3. 구독자 삭제 없이 큐를 재구성하는 경우
큐의 설정을 변경하거나 재구성하는 과정에서 기존 구독자를 DBMS_AQADM.REMOVE_SUBSCRIBER로 삭제하지 않은 채 새로운 구독자를 동일한 이름으로 다시 추가하려 할 때 발생합니다. DBA나 개발자가 수동으로 큐를 관리하는 환경에서 절차를 빠뜨리거나 이전 상태를 확인하지 않고 작업을 진행할 때 특히 자주 발생합니다. 이 경우 현재 구독자 목록을 먼저 조회하지 않은 것이 핵심 원인입니다.
해결 방법
원인 1 해결: 구독자 존재 여부를 확인한 후 조건부 등록
스크립트를 실행하기 전에 AQ$_<큐테이블명>_S 뷰나 DBA_QUEUE_SUBSCRIBERS 등의 딕셔너리를 조회하여 구독자가 이미 존재하는지 확인합니다.
-- 현재 등록된 구독자 목록 조회
SELECT name, queue, address, protocol
FROM dba_queue_subscribers
WHERE queue = 'MY_QUEUE'
AND owner = 'AQ_USER';
-- 조건부 구독자 등록 (존재하지 않을 때만 추가)
DECLARE
v_count NUMBER := 0;
v_subscriber sys.aq$_agent;
BEGIN
SELECT COUNT(*)
INTO v_count
FROM dba_queue_subscribers
WHERE queue = 'MY_QUEUE'
AND owner = 'AQ_USER'
AND name = 'MY_APP_SUBSCRIBER';
IF v_count = 0 THEN
v_subscriber := sys.aq$_agent(
'MY_APP_SUBSCRIBER', -- 구독자 이름
NULL, -- 주소 (NULL이면 로컬)
NULL -- 프로토콜
);
DBMS_AQADM.ADD_SUBSCRIBER(
queue_name => 'AQ_USER.MY_QUEUE',
subscriber => v_subscriber
);
DBMS_OUTPUT.PUT_LINE('구독자 등록 완료: MY_APP_SUBSCRIBER');
ELSE
DBMS_OUTPUT.PUT_LINE('구독자가 이미 존재합니다. 등록을 건너뜁니다.');
END IF;
END;
/
원인 2 해결: 애플리케이션 코드에 예외 처리 추가
애플리케이션 시작 시 구독자를 등록하는 로직에 ORA-24034 예외를 명시적으로 처리하여 중복 등록 시 에러 없이 계속 진행할 수 있도록 합니다.
DECLARE
v_subscriber sys.aq$_agent;
already_subscribed EXCEPTION;
PRAGMA EXCEPTION_INIT(already_subscribed, -24034);
BEGIN
v_subscriber := sys.aq$_agent(
'MY_APP_SUBSCRIBER',
NULL,
NULL
);
DBMS_AQADM.ADD_SUBSCRIBER(
queue_name => 'AQ_USER.MY_QUEUE',
subscriber => v_subscriber
);
DBMS_OUTPUT.PUT_LINE('구독자 신규 등록 성공');
EXCEPTION
WHEN already_subscribed THEN
-- 이미 등록된 경우 정상으로 처리
DBMS_OUTPUT.PUT_LINE('INFO: 구독자가 이미 등록되어 있습니다. 계속 진행합니다.');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR: ' || SQLERRM);
RAISE;
END;
/
원인 3 해결: 기존 구독자 삭제 후 재등록
큐를 재구성해야 하는 경우, 기존 구독자를 먼저 제거한 뒤 새로운 구독자를 등록합니다.
-- Step 1: 기존 구독자 삭제
DECLARE
v_subscriber sys.aq$_agent;
BEGIN
v_subscriber := sys.aq$_agent(
'MY_APP_SUBSCRIBER',
NULL,
NULL
);
DBMS_AQADM.REMOVE_SUBSCRIBER(
queue_name => 'AQ_USER.MY_QUEUE',
subscriber => v_subscriber
);
DBMS_OUTPUT.PUT_LINE('기존 구독자 삭제 완료');
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -24035 THEN
-- ORA-24035: subscriber does not exist, 무시하고 진행
DBMS_OUTPUT.PUT_LINE('구독자가 존재하지 않음. 삭제 생략');
ELSE
RAISE;
END IF;
END;
/
-- Step 2: 새 구독자 등록
DECLARE
v_subscriber sys.aq$_agent;
BEGIN
v_subscriber := sys.aq$_agent(
'MY_APP_SUBSCRIBER',
NULL,
NULL
);
DBMS_AQADM.ADD_SUBSCRIBER(
queue_name => 'AQ_USER.MY_QUEUE',
subscriber => v_subscriber
);
DBMS_OUTPUT.PUT_LINE('구독자 재등록 완료');
END;
/
-- Step 3: 등록 확인
SELECT name, queue, address, protocol, transformation
FROM dba_queue_subscribers
WHERE owner = 'AQ_USER'
AND queue = 'MY_QUEUE';
예방 방법
1. 구독자 등록 스크립트에 멱등성(Idempotency) 보장
모든 AQ 구독자 등록 스크립트는 반드시 “이미 존재하면 건너뛰고, 없으면 생성한다”는 멱등성 패턴으로 작성해야 합니다. PRAGMA EXCEPTION_INIT으로 ORA-24034를 명시적으로 처리하거나, 등록 전 DBA_QUEUE_SUBSCRIBERS를 조회하는 체크 로직을 표준 템플릿으로 만들어 팀 전체에 공유하세요. 이를 통해 배포 자동화 환경에서도 스크립트가 안전하게 반복 실행될 수 있습니다.
2. AQ 구독자 상태를 정기적으로 모니터링하는 쿼리 운영
운영 환경에서는 주기적으로 큐 구독자 현황을 확인하는 모니터링 쿼리를 스케줄러 잡(DBMS_SCHEDULER)으로 등록하거나 모니터링 시스템에 통합하여 중복 등록 시도 및 비정상 구독자를 사전에 감지할 수 있도록 관리 체계를 구축하세요.
-- 운영 환경 AQ 구독자 현황 정기 점검 쿼리
SELECT
q.owner,
q.name AS queue_name,
q.queue_type,
s.name AS subscriber_name,
s.address,
s.protocol
FROM dba_queues q
JOIN dba_queue_subscribers s
ON q.owner = s.owner
AND q.name = s.queue
WHERE q.owner NOT IN ('SYS','SYSTEM','DBSNMP')
ORDER BY q.owner, q.name, s.name;
관련 에러
- ORA-24035:
subscriber does not exist— 존재하지 않는 구독자를 삭제하거나 참조하려 할 때 발생합니다. ORA-24034와 쌍을 이루는 에러로, REMOVE_SUBSCRIBER 시 자주 함께 나타납니다. - ORA-24033:
no recipients for message— 큐에 구독자가 전혀 없는 상태에서 메시지를 발행(enqueue)할 때 발생하며, 구독자 관리 실패로 이어질 수 있습니다. - ORA-25237:
navigation option used out of sequence— AQ 메시지 탐색 순서 오류로, 구독자 설정 이상 시 연쇄적으로 발생할 수 있습니다. - ORA-24010:
QUEUE does not exist— 구독자를 등록하려는 대상 큐 자체가 존재하지 않을 때 발생하며, ADD_SUBSCRIBER 이전에 큐 존재 여부도 함께 검증해야 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.