2026년 08월 10일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-02091 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-02091 transaction rolled back 는?
ORA-02091 에러는 Oracle 데이터베이스에서 트랜잭션이 롤백되었을 때 발생하는 에러입니다. 이 에러는 단독으로 발생하기보다는 다른 에러(예: ORA-02090, ORA-00060 등)와 함께 발생하는 경우가 많으며, 트랜잭션 내에서 어떤 이유로든 커밋이 불가능한 상황이 되었을 때 Oracle이 자동으로 롤백을 수행하면서 출력됩니다. 분산 트랜잭션(Distributed Transaction), 데드락(Deadlock), 제약 조건 위반 등 다양한 상황에서 트리거될 수 있으므로 반드시 함께 출력된 에러 메시지를 확인해야 합니다.
주요 발생 원인
1. 분산 트랜잭션(Distributed Transaction) 실패
Oracle의 분산 트랜잭션 환경(Database Link 사용)에서 원격 데이터베이스와의 통신이 끊기거나, 원격 DB에서 커밋을 완료하지 못한 경우 전체 트랜잭션이 롤백됩니다. 이는 Two-Phase Commit(2PC) 프로토콜에서 준비(Prepare) 단계 또는 커밋(Commit) 단계 실패 시 자주 발생하며, ORA-02091과 함께 ORA-02050 또는 ORA-01015 에러가 동반되는 경우가 많습니다.
2. 데드락(Deadlock) 발생
두 개 이상의 세션이 서로 상대방이 보유한 잠금(Lock)을 기다리는 교착 상태가 발생하면, Oracle은 한 세션의 트랜잭션을 강제로 롤백하여 데드락을 해소합니다. 이 과정에서 ORA-00060(deadlock detected) 에러와 함께 ORA-02091이 발생하며, Alert 로그에도 관련 정보가 기록됩니다.
3. 무결성 제약 조건(Integrity Constraint) 위반
트랜잭션 내에서 FK(Foreign Key), UK(Unique Key), NOT NULL 등의 제약 조건을 위반하는 DML 작업이 있을 경우, Oracle은 해당 트랜잭션 전체를 롤백할 수 있습니다. 특히 지연된 제약 조건(Deferred Constraint) 사용 시 커밋 시점에서 위반이 감지되어 ORA-02091과 함께 ORA-02091이 출력되는 경우가 발생합니다.
해결 방법
원인 1: 분산 트랜잭션 실패 해결
먼저 현재 In-Doubt 상태의 분산 트랜잭션을 확인합니다.
-- In-Doubt 트랜잭션 조회
SELECT local_tran_id,
global_tran_id,
state,
mixed,
host,
db_user,
os_user,
commit#
FROM dba_2pc_pending;
In-Doubt 트랜잭션이 존재한다면 수동으로 커밋 또는 롤백을 수행합니다.
-- In-Doubt 트랜잭션 강제 커밋
COMMIT FORCE 'local_tran_id';
-- In-Doubt 트랜잭션 강제 롤백
ROLLBACK FORCE 'local_tran_id';
-- 처리 후 정리
EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');
Database Link 연결 상태도 함께 점검합니다.
-- Database Link 연결 테스트
SELECT * FROM dual@your_db_link_name;
-- Database Link 목록 확인
SELECT db_link, username, host FROM dba_db_links;
원인 2: 데드락 해결
데드락이 의심되면 Alert 로그와 트레이스 파일을 먼저 확인합니다.
-- 현재 잠금 대기 세션 확인
SELECT s.sid,
s.serial#,
s.username,
s.status,
s.blocking_session,
s.wait_class,
s.event
FROM v$session s
WHERE s.blocking_session IS NOT NULL;
-- 잠금 보유 세션 상세 조회
SELECT l.sid,
l.type,
l.lmode,
l.request,
l.block,
o.object_name,
o.object_type
FROM v$lock l
JOIN dba_objects o ON l.id1 = o.object_id
WHERE l.block = 1;
데드락을 유발하는 세션을 종료합니다.
-- 문제 세션 강제 종료
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
-- RAC 환경에서는 inst_id 포함
ALTER SYSTEM KILL SESSION 'sid,serial#,@inst_id' IMMEDIATE;
원인 3: 제약 조건 위반 해결
지연된 제약 조건 위반 여부를 확인합니다.
-- 지연 가능한 제약 조건 조회
SELECT constraint_name,
constraint_type,
table_name,
status,
deferrable,
deferred,
validated
FROM dba_constraints
WHERE table_name = 'YOUR_TABLE_NAME'
AND deferrable = 'DEFERRABLE';
-- 특정 트랜잭션에서 제약 조건 즉시 검사로 변경
SET CONSTRAINTS ALL IMMEDIATE;
-- 또는 특정 제약 조건만 즉시 검사
SET CONSTRAINTS fk_constraint_name IMMEDIATE;
위반 데이터를 사전에 점검하는 쿼리 예시입니다.
-- FK 위반 데이터 사전 확인
SELECT child.rowid,
child.parent_id
FROM child_table child
WHERE NOT EXISTS (
SELECT 1
FROM parent_table parent
WHERE parent.id = child.parent_id
);
-- Unique 제약 조건 위반 데이터 확인
SELECT col1, col2, COUNT(*) AS cnt
FROM your_table
GROUP BY col1, col2
HAVING COUNT(*) > 1;
예방 방법
1. 트랜잭션 범위 최소화 및 명확한 오류 처리 루틴 구현
트랜잭션을 짧고 명확하게 유지하며, 애플리케이션 레이어에서 반드시 예외 처리 블록을 구현하여 에러 발생 시 즉시 롤백이 수행되도록 합니다. PL/SQL에서는 아래와 같이 EXCEPTION 블록을 활용하고, 에러 로그를 반드시 남겨 추후 분석이 가능하도록 구성합니다.
BEGIN
-- DML 작업 수행
UPDATE your_table SET col1 = 'value' WHERE id = 1;
INSERT INTO another_table (id, col1) VALUES (1, 'value');
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
-- 에러 로그 기록
INSERT INTO error_log (err_code, err_msg, err_time)
VALUES (SQLCODE, SQLERRM, SYSDATE);
COMMIT;
RAISE;
END;
/
2. 분산 트랜잭션 모니터링 자동화
DBA_2PC_PENDING 뷰를 주기적으로 모니터링하는 스크립트를 스케줄러에 등록하고, In-Doubt 트랜잭션이 일정 시간 이상 지속될 경우 알림을 받을 수 있도록 구성합니다. DISTRIBUTED_LOCK_TIMEOUT 파라미터를 적절히 조정하여 장시간 대기를 방지하는 것도 중요합니다.
-- DISTRIBUTED_LOCK_TIMEOUT 확인 및 설정
SHOW PARAMETER distributed_lock_timeout;
ALTER SYSTEM SET distributed_lock_timeout = 60 SCOPE=BOTH;
-- 모니터링 스크립트 (DBMS_SCHEDULER 등록용)
SELECT COUNT(*) AS indoubt_count,
MIN(fail_time) AS oldest_fail_time
FROM dba_2pc_pending
WHERE state IN ('prepared', 'collecting', 'committed', 'forced commit', 'forced rollback');
관련 에러
- ORA-02050: 분산 트랜잭션이 롤백되었으며, 일부 원격 DB가 In-Doubt 상태임을 나타냅니다.
- ORA-00060: 데드락이 감지되었을 때 발생하며, ORA-02091의 주요 선행 에러입니다.
- ORA-02055: 분산 업데이트 작업 실패 시 발생하며, ORA-02091과 함께 출력됩니다.
- ORA-01013: 사용자 또는 시스템에 의해 작업이 취소될 때 발생하여 트랜잭션 롤백을 유발합니다.
- ORA-02090: 네트워크 에러나 통신 실패 시 발생하며, 분산 환경에서 ORA-02091과 자주 동반됩니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.