반응형
🧨 상황: 트랜잭션 미적용 → 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로 감싸야 합니다.
반응형
'Java' 카테고리의 다른 글
G1 GC 관리 항목별 Default 값 및 권장 설정 (1) | 2025.05.14 |
---|---|
G1 GC 영역 (Eden, Survivor, Old Gen) (0) | 2025.05.14 |
@Transactional 어디에 위치시켜야하나? (0) | 2025.05.14 |
gRPC 연동 정리 (Java vs Kotlin vs NestJS) (0) | 2025.04.02 |
Java, Kotlin, NestJS의 CI/CD 구성과 마이크로서비스 아키텍처 구성 차이 (0) | 2025.04.02 |