Spring 예외 전파여부에 따른 트랜잭션 롤백처리
Spring 예외 전파여부에 따른 트랜잭션 롤백처리
Case 1
1
2
3
4
5
6
7
8
9
10
11
@Transactional
public void insertPopularMovies() {
PopularMoviePageResponse res = getPopularMovies(1);
movieRepository.saveAll(
res.results().stream()
.map(item -> MovieEntity.of(item, 1))
.toList()
);
PopularMoviePageResponse res2 = getPopularMovies(2);
tmdb2Service.insertPopularMovies2(res2);
}
1
2
3
4
5
6
7
8
9
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertPopularMovies2(PopularMoviePageResponse res) {
movieRepository.saveAll(
res.results().stream()
.map(item -> MovieEntity.of(item, 2))
.toList()
);
throw new RuntimeException();
}
- insertPopularMovies에서 insertPopularMovies2를 호출한 형태
- insertPopularMovies2에서 임의로 RuntimeException을 throw 했다.
- insertPopularMovies2에서
REQUIRES_NEW
에 의해 트랜잭션이 분리되었어도 insertPopularMovies2의 RuntimeException()으로 인해 예외가 상위 메소드로 전파되어 insertPopularMovies의 내용도 롤백됨
Case 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Transactional
public void insertPopularMovies() {
PopularMoviePageResponse res = getPopularMovies(1);
movieRepository.saveAll(
res.results().stream()
.map(item -> MovieEntity.of(item, 1))
.toList()
);
PopularMoviePageResponse res2 = getPopularMovies(2);
try {
tmdb2Service.insertPopularMovies2(res2);
} catch (Exception e) {
log.info(e.getMessage());
}
}
1
2
3
4
5
6
7
8
9
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertPopularMovies2(PopularMoviePageResponse res) {
movieRepository.saveAll(
res.results().stream()
.map(item -> MovieEntity.of(item, 2))
.toList()
);
throw new RuntimeException();
}
- insertPopularMovies에서 insertPopularMovies2를 호출한 형태
- 이번엔 insertPopularMovies2를 try catch로 묶어서 호출
- catch에서 log만 찍고 exception을 throw하지 않으므로 insertPopularMovies에서 작업한 내용은 롤백되지 않는다. (insertPopularMovies2에서 작업한 내용만 롤백됨.)
Case 3
1
2
3
4
5
6
7
8
9
10
11
12
@Transactional
public void insertPopularMovies() {
PopularMoviePageResponse res = getPopularMovies(1);
movieRepository.saveAll(
res.results().stream()
.map(item -> MovieEntity.of(item, 1))
.toList()
);
PopularMoviePageResponse res2 = getPopularMovies(2);
tmdb2Service.insertPopularMovies2(res2);
throw new RuntimeException();
}
1
2
3
4
5
6
7
8
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertPopularMovies2(PopularMoviePageResponse res) {
movieRepository.saveAll(
res.results().stream()
.map(item -> MovieEntity.of(item, 2))
.toList()
);
}
- insertPopularMovies에서 insertPopularMovies2를 호출한 형태
- 이번엔 insertPopularMovies2 작업까지 마치고 insertPopularMovies의 마지막 부분에서 RuntimeException을 throw 했다.
- 이 경우, insertPopularMovies2는 새로운 트랜잭션으로 묶여서 commit 까지 완료되었으므로 롤백되지 않고 insertPopularMovies에서 작업한 내용만 롤백된다.
This post is licensed under CC BY 4.0 by the author.