2026년 07월 16일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-01453 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-01453 SET TRANSACTION must be first statement of transaction 는?
ORA-01453은 SET TRANSACTION 명령어가 트랜잭션의 첫 번째 문장으로 실행되지 않았을 때 발생하는 Oracle 에러입니다. SET TRANSACTION은 반드시 새 트랜잭션이 시작되는 시점, 즉 이전 트랜잭션이 COMMIT 또는 ROLLBACK으로 완전히 종료된 직후에 가장 먼저 실행되어야 합니다. 이미 DML(INSERT, UPDATE, DELETE) 또는 SELECT FOR UPDATE 등의 문장이 실행되어 트랜잭션이 시작된 상태에서 SET TRANSACTION을 호출하면 이 에러가 발생합니다.
주요 발생 원인
1. DML 실행 후 SET TRANSACTION 호출
가장 흔한 원인으로, 개발자가 INSERT, UPDATE, DELETE 등의 DML을 먼저 실행한 후 SET TRANSACTION으로 트랜잭션 속성을 변경하려 할 때 발생합니다. Oracle은 첫 번째 DML이 실행되는 순간 이미 트랜잭션을 시작한 것으로 간주하기 때문에, 그 이후에 SET TRANSACTION을 호출하면 에러가 발생합니다. 이는 애플리케이션 코드에서 트랜잭션 제어 순서를 잘못 설계한 경우가 대부분입니다.
2. 암묵적 트랜잭션 시작 후 SET TRANSACTION 호출
Oracle에서는 DDL이 아닌 DML 문장이 실행되면 명시적인 BEGIN 없이도 암묵적으로 트랜잭션이 시작됩니다. 개발자가 이 사실을 인식하지 못하고, 이미 어떤 DML이 세션 내에서 실행된 이후 SET TRANSACTION READ ONLY 또는 SET TRANSACTION ISOLATION LEVEL을 실행하면 ORA-01453이 발생합니다. 특히 Oracle Forms, JDBC, PL/SQL 프로시저 내부에서 호출 순서를 잘못 설계할 때 자주 발생합니다.
3. COMMIT/ROLLBACK 없이 반복 호출
배치 프로그램이나 루프 내에서 트랜잭션을 관리할 때, 이전 트랜잭션을 명시적으로 종료(COMMIT 또는 ROLLBACK)하지 않은 상태에서 다시 SET TRANSACTION을 호출하는 경우입니다. 세션이 지속적으로 유지되는 커넥션 풀 환경에서는 이전 작업의 트랜잭션이 남아있을 가능성이 높아, 이 에러가 더욱 빈번하게 발생합니다. 커넥션 풀에서 재사용되는 커넥션은 이전 세션 상태가 남아있을 수 있으므로 반드시 주의해야 합니다.
해결 방법
원인 1 해결: SET TRANSACTION을 가장 먼저 실행
SET TRANSACTION은 반드시 COMMIT 또는 ROLLBACK 직후, DML 실행 이전에 위치해야 합니다.
잘못된 예시:
-- 잘못된 순서: DML 먼저 실행 후 SET TRANSACTION 시도
UPDATE employees SET salary = salary * 1.1 WHERE department_id = 10;
-- ORA-01453 발생!
SET TRANSACTION READ ONLY;
올바른 예시:
-- 올바른 순서: COMMIT 후 SET TRANSACTION 먼저 실행
COMMIT;
SET TRANSACTION READ ONLY;
-- 이후 SELECT 문 실행
SELECT employee_id, salary
FROM employees
WHERE department_id = 10;
COMMIT; -- 트랜잭션 종료
원인 2 해결: ISOLATION LEVEL 설정 순서 교정
트랜잭션 격리 수준을 설정할 때도 반드시 트랜잭션 시작 전에 설정해야 합니다.
잘못된 예시:
-- 이미 암묵적 트랜잭션이 시작된 상태
INSERT INTO orders (order_id, order_date) VALUES (1001, SYSDATE);
-- ORA-01453 발생!
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
올바른 예시:
-- 이전 트랜잭션 종료
COMMIT;
-- 트랜잭션 속성 먼저 설정
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- 이후 DML 실행
INSERT INTO orders (order_id, order_date) VALUES (1001, SYSDATE);
INSERT INTO order_items (order_id, item_id, qty) VALUES (1001, 501, 3);
COMMIT;
원인 3 해결: PL/SQL 블록에서의 올바른 트랜잭션 관리
PL/SQL 프로시저나 익명 블록에서 트랜잭션을 관리할 때는 아래와 같이 명시적으로 처리합니다.
DECLARE
v_count NUMBER;
BEGIN
-- 혹시 남아있는 트랜잭션 정리
COMMIT;
-- SET TRANSACTION은 트랜잭션 시작 전에만 가능
-- PL/SQL 블록 내에서는 DBMS_TRANSACTION 패키지 사용 권장
DBMS_TRANSACTION.READ_ONLY;
SELECT COUNT(*) INTO v_count
FROM employees
WHERE hire_date > TO_DATE('2020-01-01', 'YYYY-MM-DD');
DBMS_OUTPUT.PUT_LINE('대상 직원 수: ' || v_count);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END;
/
커넥션 풀 환경에서의 해결 방법
-- 커넥션을 재사용하기 전 반드시 트랜잭션 상태 초기화
-- 애플리케이션 레이어에서 커넥션 반환 전 실행
ROLLBACK; -- 미완료 트랜잭션 롤백
-- 이후 SET TRANSACTION 정상 실행
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 업무 로직 실행
UPDATE accounts SET balance = balance - 5000 WHERE account_id = 1001;
UPDATE accounts SET balance = balance + 5000 WHERE account_id = 1002;
COMMIT;
예방 방법
1. 트랜잭션 시작 전 명시적 COMMIT/ROLLBACK 습관화
모든 트랜잭션 제어 코드는 이전 트랜잭션이 반드시 종료된 이후에만 SET TRANSACTION을 사용하도록 코딩 표준을 수립해야 합니다. 특히 커넥션 풀 환경에서는 커넥션을 반납할 때 반드시 COMMIT 또는 ROLLBACK을 수행하고, 커넥션을 다시 획득할 때 깨끗한 상태임을 보장하는 로직을 애플리케이션 프레임워크 수준에서 구현하는 것이 좋습니다. Spring Framework를 사용하는 경우 @Transactional 어노테이션과 트랜잭션 매니저를 올바르게 설정하여 트랜잭션 경계를 명확히 정의하십시오.
2. DBMS_TRANSACTION 패키지 활용 및 코드 리뷰 프로세스 강화
PL/SQL 코드에서 SET TRANSACTION 대신 DBMS_TRANSACTION 패키지의 프로시저(READ_ONLY, READ_WRITE, ADVISE_COMMIT 등)를 사용하면 보다 안전하고 유연하게 트랜잭션을 제어할 수 있습니다. 코드 리뷰 단계에서 SET TRANSACTION 명령어가 포함된 코드는 반드시 그 앞에 COMMIT/ROLLBACK이 있는지 확인하는 체크리스트를 운영하고, CI/CD 파이프라인에 정적 분석 도구를 통합하여 트랜잭션 순서 오류를 사전에 탐지하는 것을 권장합니다.
관련 에러
- ORA-01453 와 함께 자주 언급되는 관련 Oracle 에러들은 다음과 같습니다.
- ORA-01456:
SET TRANSACTION READ ONLY상태에서 DML을 수행할 때 발생하는 에러로, READ ONLY 트랜잭션의 제약을 위반했을 때 나타납니다. - ORA-02089: 분산 트랜잭션(Distributed Transaction) 환경에서 COMMIT이 허용되지 않는 상황에 발생하며, 트랜잭션 관리와 밀접한 관련이 있습니다.
- ORA-01555: Snapshot too old 에러로,
SET TRANSACTION READ ONLY를 사용하는 장시간 읽기 전용 트랜잭션에서 UNDO 데이터가 부족할 때 발생할 수 있습니다. - ORA-00036:
SET TRANSACTION관련 재귀적 SQL 레벨 초과 에러로, 복잡한 트랜잭션 제어 로직에서 간헐적으로 연관되어 나타납니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.