개발 실수
@Transactional 실수
No-ah98
2022. 9. 13. 21:46
오늘은 프로젝트 중 팀원에게 피드백 받은 내용을 포스팅 하려고 합니다.
상황
하나의 요청(Post)으로 인해 데이터 리스트들을 두 개의 엔티티(A, B)에 저장해야 하는 상황.
이때 저는 A Controller에서 for문으로 (A, B) Service의 save 함수를 호출 했습니다.
막상 코드를 작성할 때는 데이터에 오류가 생기더라도 save 함수에 @Transactional로 롤백이 될 거라고 생각했습니다.
하지만, 팀원이 "for문에서 save 함수가 하나라도 오류가 나면 전부 다 롤백이 되어야 할 것 같아요" 라는 말을 듣고
for문 로직을 service로 옮겼습니다.
수정 전
@Controller
public class TogehterController{
...
@PostMapping("/recruit/{board_id}/{article_id}/{member_id}")
public String form(@ModelAttribute("togetherForm") TogetherForm togetherForm, @PathVariable("board_id") Long boardId, @PathVariable("article_id") Long articleId, @PathVariable("member_id") Long memberId) {
List<Long> ids = togetherForm.getIds(); // 작성자가 선택한 댓글 작성자들
ids.add(memberId); // 작성자 아이디
System.out.println("ids.size() = " + ids.size());
// 문제가 된 코드
for(int i = 0; i < ids.size(); i++){
togetherService.save(articleId, ids.get(i));
Long reviewerId = ids.get(i);
for(int j = 0; j < ids.size(); j++){
Long revieweeId = ids.get(j);
if(reviewerId != revieweeId){
System.out.println("revieweeId = " + revieweeId);
System.out.println("reviewerId = " + reviewerId);
reviewService.save(articleId, revieweeId, reviewerId);
}
}
}
return "redirect:/board/complete/%d/%d".formatted(boardId, articleId);
}
}
수정 후
@Service
public class TogetherService {
. . .
@Transactional
public void saveTogetherAndReview(Long articleId, List<Long> ids) {
for(int i = 0; i < ids.size(); i++){
this.save(articleId, ids.get(i));
Long reviewerId = ids.get(i);
for(int j = 0; j < ids.size(); j++){
Long revieweeId = ids.get(j);
if(reviewerId != revieweeId){
System.out.println("revieweeId = " + revieweeId);
System.out.println("reviewerId = " + reviewerId);
reviewService.save(articleId, revieweeId, reviewerId);
}
}
}
}
}
기능 완료에 초점을 맞추다 보니, 자잘한 실수가 있었던 거 같습니다.
추가로 @Transactional에 대해 정리를 해야 겠다고 생각했습니다.