개발 실수

@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에 대해 정리를 해야 겠다고 생각했습니다.