Oracle에서 병렬 DELETE나 UPDATE 후 바로 SELECT 문을 실행했더니 `ORA-12838: 병렬로 수정한 후 객체를 읽거나 수정할 수 없습니다` 오류가 발생했다면, 너무 놀라지 마세요.
이 오류는 데이터베이스가 망가졌거나 쿼리 문법이 잘못된 게 아니라, 병렬 작업 후 커밋을 생략한 경우에 자주 나타나는 전형적인 상황입니다.
이 글에서는 그 원인과 해결법, 그리고 자주 묻는 질문까지 모두 정리해드립니다.
ORA-12838 오류 해결법 - 병렬 작업 후 SELECT 오류? 이 한 줄이면 해결됩니다
ORA-12838 오류란 무엇인가?
병렬 작업 후 COMMIT 없이 테이블을 다시 조회하면 발생
`ORA-12838`은 병렬로 DML(데이터 수정) 작업을 수행한 후 트랜잭션을 커밋하지 않고 같은 세션에서 같은 객체에 접근하려 할 때 발생하는 오류입니다.
Oracle은 병렬 DML 작업의 안정성을 보장하기 위해 커밋 전까지 해당 테이블을 다시 읽거나 수정하지 못하도록 제한합니다.
상황 | 발생 여부 |
---|---|
병렬 DELETE 후 바로 SELECT | ❌ 오류 발생 |
병렬 DELETE 후 COMMIT 후 SELECT | ✅ 정상 작동 |
병렬 없이 DELETE 후 SELECT | ✅ 정상 작동 |
이 오류는 DELETE, UPDATE, MERGE 모두에 해당되며, 특히 대용량 데이터를 병렬로 처리하는 배치 작업 시 흔히 마주하게 됩니다.
왜 Oracle은 이런 제한을 두는가?
병렬 DML은 여러 프로세스가 동시에 테이블을 수정하기 때문에, 커밋되기 전까지는 데이터의 일관성이 확보되지 않습니다.
따라서 Oracle은 병렬 수정 직후 해당 객체에 SELECT나 또 다른 DML을 금지하여 데이터 무결성을 유지합니다.
ORA-12838 해결 방법
COMMIT을 명시적으로 넣기
가장 쉬운 해결법은 병렬 작업 후 커밋을 추가하는 것입니다.
-- 병렬 DELETE 예시
DELETE /*+ parallel(visitor_logs, 4) */ FROM visitor_logs
WHERE VISIT_TIMESTAMP < TRUNC(SYSDATE) - 7;
COMMIT;
-- 이후 SELECT 정상 작동
SELECT * FROM visitor_logs WHERE ROWNUM <= 10;
병렬 사용 자체를 제거하기
병렬 처리가 굳이 필요하지 않은 상황이라면 병렬 힌트를 제거하거나 세션에서 병렬 DML을 비활성화하세요.
-- 힌트 제거
DELETE FROM visitor_logs
WHERE VISIT_TIMESTAMP < TRUNC(SYSDATE) - 7;
-- 혹은 세션 수준에서 병렬 DML 비활성화
ALTER SESSION DISABLE PARALLEL DML;
해결 방법 | 설명 |
---|---|
COMMIT 실행 | 병렬 DML 후 커밋하면 오류 방지 |
병렬 힌트 제거 | `/*+ parallel(...) */` 삭제 |
세션 병렬 DML 비활성화 | `ALTER SESSION DISABLE PARALLEL DML` |
병렬 설정 여부 확인
내가 병렬 DML을 사용하고 있는지 모르겠다면 아래 명령어로 확인해보세요.
SHOW PARAMETER parallel;
SQL | SELECT 문의 기본 구조와 활용 방법 |
SQL 쿼리로 상품 정보 조회하기 - 실전 가이드 |
Oracle SQL에서 상위 N개 데이터만 선택하는 방법 - ROWNUM과 LIMIT의 차이점 |
MySQL 저장된 시간이 JavaScript에서 조회한 시간 다를 때 해결 방법 |
축구팀 관리 프로젝트 22일차 - 중간발표 끝, SQL 인젝션 해결방안 |
자주 묻는 질문 Q&A
Q1. 병렬 힌트를 쓰지 않았는데도 ORA-12838이 발생할 수 있나요?
A. 네, 가능합니다.
`ALTER SESSION ENABLE PARALLEL DML` 명령으로 세션에서 병렬 DML이 활성화된 상태일 경우, SQL에 병렬 힌트가 없어도 Oracle이 자동 병렬 처리를 수행할 수 있습니다.
이 경우도 COMMIT이 필요합니다.
Q2. 병렬 작업 후 꼭 COMMIT을 해야 하나요?
A. 네.
병렬 DML 작업을 수행한 후에는 COMMIT이나 ROLLBACK을 반드시 해야 해당 테이블에 다시 접근할 수 있습니다.
이 규칙을 무시하면 ORA-12838이 계속 발생합니다.
Q3. 병렬 사용이 필요한데, 오류 없이 계속 작업하려면?
A. 병렬 DML 후에는 중간에 SELECT, INSERT 등을 하지 않고 바로 COMMIT 또는 ROLLBACK을 하고, 그 다음에 후속 작업을 하세요.
또는 병렬 DML을 사용한 트랜잭션은 다른 테이블에서만 후속 작업을 수행하는 것도 방법입니다.
병렬 DELETE 후엔 잊지 말고 COMMIT!
성능을 높이되 안정성도 챙기려면 반드시 커밋
병렬 작업은 대용량 데이터를 빠르게 처리할 수 있는 강력한 기능이지만, 그에 따른 제약도 존재합니다.
ORA-12838 오류는 병렬 작업 후 발생하는 안전장치이며, 그 해결법은 아주 간단합니다—바로 `COMMIT`입니다.
특히 배치 작업, 자동화 스크립트 등에서 병렬 DML을 사용하는 경우 커밋을 빼먹지 않도록 주의하세요.
하지만 이제는 해결 방법도 익혔으니, 당황할 일은 없겠죠?
▼ 함께 보면 좋은 글 ▼
SQL 쿼리로 상품 정보 조회하기 - 실전 가이드 |
최종프로젝트 11일차 - 경기장 예약 완료, ORM 쿼리 복잡해질 때 |
최종프로젝트 12일차 경기 일정 조회 작업, 쿼리 최적화에 대해 |
웹 개발에서 캐시 무효화를 위한 쿼리 문자열 활용하기 - 꼭 알아야 할 실전 팁 |
'Programming & Platform > SQL' 카테고리의 다른 글
SQL 쿼리로 상품 정보 조회하기 - 실전 가이드 (0) | 2024.06.06 |
---|---|
MySQL 저장된 시간이 JavaScript에서 조회한 시간 다를 때 해결 방법 (1) | 2024.01.03 |