Java

트랜잭션이 적용되지 않고 AutoCommit 상태일 때 발생할 수 있는 문제점

마시멜로를찾아서 2025. 5. 14. 10:44
반응형

🧨 상황: 트랜잭션 미적용 → AutoCommit 상태

  • Spring에서 @Transactional이 제대로 작동하지 않으면,
    JDBC 커넥션은 기본적으로 AutoCommit = true 상태로 동작합니다.
  • 즉, 각 SQL이 실행될 때마다 즉시 커밋되며 롤백이 불가능한 상태입니다.

⚠️ 발생 가능한 문제점 4가지

1. 데이터 불일치 / 부분 저장 문제

❌ 예시 상황

java
 
// 예: 고객 주문 저장 로직
insertOrder();        // 주문 마스터
insertOrderItems();   // 주문 상세
updateStock();        // 재고 차감

insertOrder()는 성공했고, insertOrderItems()에서 오류 발생 →
첫 insert는 이미 커밋되었기 때문에 롤백이 불가능
주문은 존재하지만 주문 품목이 없음 = 데이터 무결성 붕괴

💣 문제

  • 논리적으로는 하나의 트랜잭션이지만,
  • AutoCommit 상태에서는 작업이 쪼개져서 처리됨 → 복구 불가능

2. 동시성 문제 / Dirty Read 발생

트랜잭션이 없으면 읽기/쓰기 작업 간 경계가 없어져
다른 세션에서 중간 결과를 읽거나 덮어쓰는 현상 발생

예: 다른 트랜잭션이 아직 완료되지 않은 데이터를 읽고 변경해버림
비즈니스 로직 간 충돌


3. Rollback 불가

try-catch로 예외를 잡아도, 이미 AutoCommit 되어버린 SQL은 원복 불가

java
 
try {
    insert();   // AutoCommit됨
    update();   // 여기서 실패
} catch (Exception e) {
    // rollback(); ← rollback 불가. 이미 insert는 반영됨
}

4. DB 락이 의도치 않게 오래 유지되거나 즉시 해제됨

트랜잭션이 없으면 락도 SQL 단위로 발생 및 해제됨
→ 일부 처리 중간에는 잠금 없이 잘못된 동시처리가 발생하거나
→ 반대로 의도한 락 지속이 되지 않아 Dirty Update 발생 가능성 존재


📌 트랜잭션 없이 AutoCommit이 특히 위험한 영역

상황설명
마스터/상세 INSERT 상위 테이블만 저장되고 하위 테이블은 실패하면 참조 무결성 깨짐
계좌 이체, 포인트 적립 등 입금은 되었지만 출금이 실패하면 금액 오류 발생
통계 수치 갱신 수치 증가 후 중단 시 이중 집계 가능
로깅 / 추적 테이블 삽입 실패 오류 발생 시 아무 로그도 남지 않음
 

✅ 해결책 요약

방법설명
@Transactional 구현 클래스에 선언 프록시를 통한 트랜잭션 적용 보장
REQUIRES_NEW 등의 전파 속성 명시 독립 트랜잭션 제어 필요 시
rollbackFor = Exception.class 명시 예외 상황에 명확하게 롤백 설정
테스트 시 @Commit, @Rollback 명시 트랜잭션 테스트 커버리지 확보
 

✅ 결론

트랜잭션 미적용 상태(AutoCommit)는
부분 커밋, 복구 불가능, 동시성 충돌, 데이터 무결성 파괴 등 심각한 문제를 일으킬 수 있습니다.

항상 중요한 DML 로직은 명확히 @Transactional로 감싸야 합니다.

반응형