요구 사항 및 개발

프로젝트를 진행하면서 다음과 같은 요구 사항이 있었다.

팀장은 팀원 삭제를 나머지 팀원들에게 요청할 수 있다. 이때 팀원들에게 이메일을 통해 삭제 허가 요청을 보낸다. (삭제 허가 요청을 보낼 때는 아직 팀원을 삭제하지는 않는다.)

이 요구 사항을 만족하기 위해 다음과 같이 개발을 했다.

@Service
@Transcational
@RequiredArgsConstructor
public class TeamService {

		private final EmailService emailService;

		public void requestToRemoveMember(Long excludedMemberId, Long leaderId) {
				// 1. id를 통해 entity를 찾는다. 이때 팀장인지 여부도 확인한다.
				// 2. 삭제 허가에 사용할 인증 코드를 생성한다.
				// 3. 인증 코드를 redis에 저장한다.

				// 4. 인증 코드와 함께 삭제 허가 요청 이메일을 전송한다.
				for (Member member : members) {
						emailService.sendEmail(fromEmail, member.getEmail(), emailTitle, emailContent);
				}
		}
}

는 에 직접 의존한다.

TeamServiceEmailService에 직접 의존한다.

문제 정의

TeamService#requestToRemoveMember()는 몇가지 특징이 있다.

위와 같이 구현하는 경우 다음과 같은 문제가 있다.

  1. 트랜잭션 내부에서 외부 API를 사용하므로 DBMS 서버에 영향을 미칠 수 있다.
  2. 사용을 마치면 바로 반환해야 하는 DB 커넥션이 불필요하게 낭비되고 있다.
  3. 이메일 전송은 시간이 오래걸리는 작업이므로 해당 API에 대한 요청이 많아지면 서버에 부하가 발생할 수 있다. 또한 API 응답 시간이 너무 길어진다.
  4. 외부 API에 직접적인 영향을 받는다. 외부 API 시스템 장애로 발생하는 문제에 대한 회복은 어떻게 할지 고민이 필요하다.

추가로 고려해보면 좋을 문제는 다음과 같다.