반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 파라메트릭
- 물채우기
- 13908
- upper_bound
- OFFSET
- 소프티어
- 경력
- 처우협의
- boj #19237 #어른 상어
- 성적평가
- 백트래킹
- dfs
- softeer
- @P0
- 처우산정
- compose
- msSQL
- incr
- 연결요소
- BOJ
- 백준
- 오퍼레터
- BFS
- 6987
- 기술면접
- 퇴사통보
- Kafka
- 매개변수탐색
- 이분탐색
- Docker
Archives
- Today
- Total
기술 블로그
@Transactional 어노테이션의 역할과 의미 본문
728x90
반응형
@Transactional 어노테이션의 역할과 의미
@Transactional 어노테이션은 스프링 프레임워크에서 데이터베이스 트랜잭션을 관리하기 위해 사용됩니다. 트랜잭션은 "모두 실행되거나 아무것도 실행되지 않아야 하는" 작업 단위입니다.
@Transactional의 핵심 기능
- 원자성(Atomicity): 트랜잭션 내의 모든 작업이 성공적으로 완료되거나, 오류 발생 시 모두 롤백됩니다.
- 일관성(Consistency): 트랜잭션 전후로 데이터베이스는 일관된 상태를 유지합니다.
- 격리성(Isolation): 동시에 실행되는 트랜잭션들이 서로 영향을 주지 않습니다.
- 지속성(Durability): 트랜잭션이 완료되면 그 결과는 영구적으로 저장됩니다.
작동 방식
@Service
public class CommentService {
private final CommentRepository commentRepository;
// 생성자 주입
public CommentService(CommentRepository commentRepository) {
this.commentRepository = commentRepository;
}
@Transactional
public void deleteComment(Long commentId) {
// 1. 댓글 조회
CommentV2 comment = commentRepository.findById(commentId)
.orElseThrow(() -> new RuntimeException("댓글을 찾을 수 없습니다"));
// 2. 댓글 삭제
commentRepository.delete(comment);
// 3. 부모 댓글 처리
if (!comment.isRoot()) {
// 부모 댓글 관련 로직
// 이 시점에서 comment 객체는 자바 메모리에 여전히 존재함
}
// 메소드가 정상적으로 종료되면 이 시점에서 트랜잭션 commit
// 예외 발생시 자동으로 rollback
}
}
트랜잭션 생명주기
- 트랜잭션 시작: @Transactional 메소드가 호출되면 트랜잭션이 시작됩니다.
- 작업 수행: 메소드 내부의 모든 데이터베이스 작업은 하나의 트랜잭션으로 묶입니다.
- 커밋 또는 롤백:
- 정상 종료: 메소드가 예외 없이 완료되면 트랜잭션이 커밋됩니다.
- 예외 발생: 메소드 내에서 예외가 발생하면 트랜잭션이 롤백됩니다.
왜 삭제 후에도 객체를 사용할 수 있는가?
@Transactional
private void delete(CommentV2 comment) {
commentRepository.delete(comment); // 이 시점에는 DB에 DELETE SQL이 즉시 실행되지 않음
if(!comment.isRoot()) { // comment 객체는 메모리에 여전히 존재하므로 메소드 호출 가능
// 다른 작업 수행
}
// 메소드 종료 시 트랜잭션 커밋, 이때 실제 DELETE SQL이 DB에 전송됨
}
JPA는 성능 최적화를 위해 "쓰기 지연(write-behind)" 전략을 사용합니다. delete() 메소드를 호출하면:
- 영속성 컨텍스트에서 엔티티를 제거 대상으로 표시합니다.
- 실제 SQL은 트랜잭션이 커밋될 때 실행됩니다.
- 자바 객체로서의 comment는 여전히 메모리에 존재하므로 속성이나 메소드를 계속 사용할 수 있습니다.
이것이 delete() 후에도 comment.isRoot()와 같은 메소드를 호출할 수 있는 이유입니다.
728x90
반응형
'JAVA' 카테고리의 다른 글
@Transactional과 프록시 패턴의 관계 (0) | 2025.04.16 |
---|---|
CountDownLatch (0) | 2025.04.10 |
Executors.newFixedThreadPool() (0) | 2025.04.10 |
직렬화(Serialization)와 역직렬화(Deserialization), transient 변수 (0) | 2023.09.07 |
어노테이션(Annotation) (0) | 2020.06.07 |