'ORA-04068: 패키지의 기존 상태가 버려졌습니다' 오류는 오브젝트에 대한 리컴파일 등의 이슈로 발생할 수 있습니다.
오라클에서는 'Global Area'라고 하는 메모리 영역 또는 공유 영역이 있습니다. 크게 3가지가 있는데요, 시스템 단위, 프로세스 단위, 유저 단위가 있습니다.
- SGA ( System Global Area ) 시스템 글로벌 영역
- PGA ( Process Global Area ) 프로세스 글로벌 영역
- UGA ( User Global Area ) 유저 글로벌 영역
패키지 상태는 기본적으로 UGA, 즉 각 유저에 속하는 영역입니다. 그리고 패키지 상태는 세션 수명 동안 지속되는데요, 세션이 유지되고 있는 상태에서 패키지의 상태가 변경되는 경우에 해당 'ORA-04068: 패키지의 기존 상태가 버려졌습니다' 오류가 발생하며, 해결 방법을 알아보도록 하겠습니다.
패키지의 기존 상태가 UGA 세션 동안 유지되는 것 예외
- 패키지가 SERIALLY_REUSABLE 일 때
- 패키지 바디가 리컴파일 될 때
- 패키지의 인스턴스가 무효화 되거나, 재검증 될 때
PRAGMA SERIALLY_REUSABLE
보통 이렇게 해결하고 있는데요, 패키지에 SERIALLY_REUSABLE 프라그마를 설정하여 패키지 상태를 SGA에 저장하여 사용하는 방법입니다.
패키지가 SERIALLY_REUSABLE인 경우, 패키지 상태는 다음의 경로에 저장합니다.
작업 영역(work area) <= 풀(pool) <= 시스템 글로벌 영역(SGA) [작업영역이 풀에 속하고, 풀이 시스템 글로벌 영역에 속합니다]
이때 패키지 상태는 '서버 콜' 중에만 유지가 되고, '서버 콜'이 종료되면 '작업영역'은 다시 '풀'로 돌아간답니다. 그리고 '서버 콜'의 후속참조가 계속 이루어지는 경우, '풀'에 있던 패키지를 재사용합니다.
기본 패키지
CREATE OR REPLACE PACKAGE pkg IS
n NUMBER := 5;
END;
/
CREATE OR REPLACE PACKAGE BODY pkg IS
BEGIN
n := 5;
END;
/
SERIALLY_REUSABLE 패키지
CREATE OR REPLACE PACKAGE pkg IS
PRAGMA SERIALLY_REUSABLE;
n NUMBER := 5;
END;
/
CREATE OR REPLACE PACKAGE BODY pkg IS
PRAGMA SERIALLY_REUSABLE;
BEGIN
n := 5;
END;
/
패키지에서 사용하는 전역 변수를 지역 변수로 수정
이렇게 해결은 안 해봤는데, 전역변수를 지역변수로 수정하여 해결하는 방법도 있다고 하더라고요.
패키지는 하나 이상의 변수, 상수, 또는 커서를 선언하면 상태 관리 대상인데요, 만약 지역변수로 설정하여 해결할 수 있다면, 상수는 그대로 놓아두고 전역변수의 지역변수 화 처리 하였을 때, 해결이 가능한지는 테스트를 안 해보았어요. 이 방법으로 해결할 수 있는가에 대한 자료는 확인이 필요해 보입니다. 상수나 커서가 없는 단순 패키지에서는 유효할 것으로 보입니다만, 그외의 경우에는 적용이 힘들지 않을까 생각하고 있습니다.