Oracle ORA-24034 오류 원인과 해결 방법 완벽 가이드

ORA-24034
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 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기