JSCODE Logo
프로그래밍 과외블로그후기멘토진
회사명 : JSCODE대표 : 박재성사업자 등록번호 : 244-22-01557통신판매업 : 제 2023-인천미추홀-0381 호
학원 명칭 : 제이에스코드(JSCODE)원격학원학원설립ㆍ운영 등록번호 : 제6063호

서울특별시 구로구 경인로 20가길 11(오류동, 아델리아)

Copyright ⓒ 2025 JSCODE - 최상위 현업 개발자들의 프로그래밍 교육 All rights reserved.

이용약관개인정보처리방침
← 블로그 목록으로 돌아가기

게시글 작성 API 로직 수행 중, 중간에 에러가 발생하면 어떻게 될까?

JSCODE 박재성
JSCODE 박재성
2025-12-06
author
JSCODE 박재성
category
MSA
createdAt
Dec 6, 2025
series
비전공자도 이해할 수 있는 MSA 입문/실전
slug
error-handling-in-post-creation
type
post
updatedAt
Dec 6, 2025 05:43 AM

✅ 게시글 작성 API 로직 수행 중, 중간에 에러가 발생하면 어떻게 될까?

👨🏻‍🏫
게시글 작성 API 로직이 ‘포인트 차감 → 게시글 저장 → 활동 점수 적립’ 구성으로 이루어져 있다. ‘포인트 차감, 게시글 저장, 활동 점수 적립’은 기획상 하나로 묶인 작업이기 때문에 이 중에 하나라도 실패하면 전체가 실패해야 한다. 즉, 활동 점수 적립에 실패하면 게시글 저장도 실패해야 하고 포인트 차감도 실패해야 하는 게 정상일 것이다. 정말 이렇게 작동하는 지 확인해보자.
 
  1. 활동 점수 증가 API에 요청을 보내면 에러가 발생하도록 만들기
    1. 활동 점수를 증가시키다 실패하는 경우를 가정하기 위해, 에러 발생시키는 코드를 추가하자.
      service/UserService
      @Service public class UserService { ... @Transactional public void addActivityScore( AddActivityScoreRequestDto addActivityScoreRequestDto ) { User user = userRepository.findById(addActivityScoreRequestDto.getUserId()) .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다.")); user.addActivityScore(addActivityScoreRequestDto.getScore()); userRepository.save(user); throw new RuntimeException("에러 발생"); } }
       
  1. user-service 서버 재실행시키기
    1.  
  1. 테스트를 위해 DB 데이터 정리하기
    1. 활동 점수 0으로 바꾸기
      1. notion image
         
    2. 포인트 데이터 1000점으로 맞춰놓기
      1. notion image
         
    3. 게시글 데이터 전부 삭제하기
      1. notion image
       
  1. 게시글 생성 API 요청 보내기
    1. notion image
      게시글 작성 API 로직의 ‘포인트 차감 → 게시글 저장 → 활동 점수 적립’ 중 ‘활동 점수 적립’ 단계에서 에러가 발생했기 때문에 게시글 작성 API 자체가 실패했다. 이렇게만 봤을 때는 의도한대로 ‘활동 점수 적립’이 실패함으로써 ‘게시글 작성’도 실패하고, ‘포인트 차감’도 실패한 것처럼 보인다. 정말 그렇게 작동했는 지 DB를 확인해보자.
       
  1. DB 확인하기
    1. notion image
      notion image
      notion image
      DB를 보면 게시글 작성도 되지 않았고 사용자 활동 점수도 쌓이지 않았는데, 포인트 차감은 된 걸 확인할 수 있다. 왜 이런 현상이 발생한 걸까?
 
 

✅ 원인 분석

모놀리식 아키텍처와 달리 MSA 환경에서는 서비스마다 DB가 분리되어 있다. 그래서 서로 다른 DB에서 처리하는 여러 작업(포인트 차감, 게시글 작성, 활동 점수 적립)을 하나의 트랜잭션으로 묶을 수 없다. 그러다보니 에러가 발생했을 때 어떤 작업은 실패했는데, 어떤 작업은 성공하는 모순된 상황이 발생한 것이다. 코드를 보면서 조금 더 자세히 살펴보자.
 
BoardService의 ‘게시글 작성’ 비즈니스 로직
@Transactional public void create(CreateBoardRequestDto createBoardRequestDto) { // 게시글 작성 전 100 포인트 차감 pointClient.deductPoints(createBoardRequestDto.getUserId(), 100); // 게시글 작성 Board board = new Board( createBoardRequestDto.getTitle(), createBoardRequestDto.getContent(), createBoardRequestDto.getUserId() ); this.boardRepository.save(board); // 롤백 // 게시글 작성 시 작성자에게 활동 점수 10점 부여 userClient.addActivityScore(createBoardRequestDto.getUserId(), 10); // 에러 발생 }
  • userClient.addActivityScore(...)에서 에러가 발생하는 순간 @Transactional 어노테이션 때문에 게시글 저장(this.boardRepostiory.save())이 롤백(rollback)된다.
 
PointService의 ‘포인트 차감’ 비즈니스 로직
@Transactional public void deductPoints(DeductPointRequestDto deductPointRequestDto) { Point point = pointRepository.findByUserId(deductPointRequestDto.getUserId()) .orElseThrow(() -> new IllegalArgumentException("사용자의 포인트 정보를 찾을 수 없습니다.")); point.deductAmount(deductPointRequestDto.getAmount()); pointRepository.save(point); }
  • ‘포인트 적립’ 비즈니스 로직에서는 에러가 발생하지 않았기 때문에 포인트 적립(pointRepository.save())이 롤백(rollback)되지 않고 커밋(commit)된다.
 
UserService의 ‘활동 점수 증가’ 비즈니스 로직
@Transactional public void addActivityScore( AddActivityScoreRequestDto addActivityScoreRequestDto ) { User user = userRepository.findById(addActivityScoreRequestDto.getUserId()) .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다.")); user.addActivityScore(addActivityScoreRequestDto.getScore()); userRepository.save(user); // 롤백 throw new RuntimeException("에러 발생"); }
  • ‘활동 점수 증가’ 비즈니스 로직에서는 에러가 발생했기 때문에 @Transactional에 의해 ‘활동 점수 증가(userRepository.save())’가 롤백(rollback)된다.
 
그림으로 표현하면 다음과 같다.
notion image
 
👨🏻‍🏫
이 문제를 해결하려면 어떻게 코드를 구현해야 하는 지 다음 강의에서 알아보자.
 
author
JSCODE 박재성
category
MSA
createdAt
Dec 6, 2025
series
비전공자도 이해할 수 있는 MSA 입문/실전
slug
type
series-footer
updatedAt
Dec 6, 2025 05:45 AM
📎
이 글은 비전공자도 이해할 수 있는 MSA 입문/실전 강의의 수업 자료 중 일부입니다.