[스프링부트 #7] Service Layer 개념 정리

서비스 계층의 역할과 전반적 개념에 대해서 정리하였습니다.
도경원's avatar
Aug 09, 2025
[스프링부트 #7] Service Layer 개념 정리

1. 서비스는 비즈니스의 중심이다.

Service Layer의 3가지 핵심

  • 비즈니스 로직 수행 (업무 규칙)
  • 트랜잭션 관리 (@Transactional)
  • 응답 DTO 생성 또는 위임
실무에서는 3번을 Controller에서 맡기도 하지만, 1, 2번은 무조건 Service에서 책임져야 한다.

2. 서비스는 “조각”들의 조립소이다.

  • Controller는 "외부 인터페이스(버튼, API 요청)"일 뿐.
  • 실질적인 로직은 Service에 있어야 유지보수가 용이하다.
  • 비즈니스 동작은 보통 이렇게 구성된다
💬
예) 이체하기 (Transfer)
  1. 출금 계좌의 잔액 차감 (update)
  1. 입금 계좌의 잔액 증가 (update)
  1. 로그 테이블에 기록 남김 (insert)

3. 로그는 선택이 아니라 필수이다.

이체할 때 발생하는 문제

  • 출금/입금은 완료됐는데, 나중에 "내역을 볼 수 없다면?"
  • 따라서 로그 테이블은 반드시 있어야 함
💬
[이체 로그 테이블 예시]
  • 출금계좌 ID
  • 입금계좌 ID
  • 금액
  • 발생시각
출금 전 잔액은 안 남는다. 그러므로 모든 내역은 반드시 insert로 로그화해야 나중에 회계 처리나 감사가 가능하다.

4. SRP원치과 “레고 쿼리” 사고방식

SRP = 단일 책임 원칙
  • 한 함수는 한 가지 책임만 가져야 한다.
  • 하나의 큰 통합 쿼리보다, 레고처럼 작은 기능의 조합(update, insert) 으로 구성하는 게 좋다.
  • 이유? 디버깅, 테스트, 확장성, 협업이 쉬워진다.

5. 트랜잭션은 서비스의 핵심 제어권

트랜잭션은 일의 최소 단위이다.

트랜잭션이 필요한 작업

  • write 작업(insert, update, delete)
  • 원자성 보장이 필요한 경우

트랜잭션이 생략 가능한 작업

  • read 작업(select) : 단, 실무에서는 조회 중간에 다른 작업이 끼면 안되는 상황이면 select도 트랜잭션을 건다.

6. 트랜잭션의 핵심 : ACID 속성 중 A와 I

원자성 (Atomicity)

  • 하나라도 실패하면 전부 롤백
  • 예: 출금 성공했는데 입금 실패하면? → 전체 롤백돼야 함
  • 실생활 비유: 메로나와 쌍쌍바 묶음 판매 → 하나만 사는 건 불가!

고립성 (Isolation)

  • 동시에 작업하는 사용자끼리 데이터가 엉키지 않도록 제어
  • 비유: 짱구가 메로나 있는지 확인 후 사러 갔는데, 그새 누가 사가버림 → 데이터 꼬임
  • 팬텀현상(Phantom Read) 방지 필요
  • 고립성은 선택적: 상황 따라 조절 가능 (4단계의 격리 수준)

7. 함수명에는 비즈니스 의도를 담자

  • transfer(), deposit(), withdraw(), updatePassword()
    • → 이런 이름이 바로 “이 코드가 무엇을 하는가”를 말해주는 핵심이다.
즉, 서비스 계층에서 가장 중요한 건 메서드명이다.

8. Controller는 마치 어댑터 (빠꿔끼는 용도)

  • Controller는 디바이스나 화면(API, 브라우저, 앱)에 따라 바뀔 수 있다
  • 반면, Service는 절대 바뀌지 않음
  • 따라서 비즈니스 로직이 없어도 Controller에서 Service를 반드시 호출하는 게 좋다
 
Share article

Gyeongwon's blog