서비스 레이어란
서비스 레이어는 비즈니스 로직을 캡슐화하고 데이터 액세스 레이어와 프레젠테이션 레이어 사이에서 중재자 역할을 한다.
서비스 레이어는 애플리케이 핵심 비즈니스 로직을 구현하고, 데이터의 일관성과 무결성을 유지하는 중요한 기능을 수행한다.
서비스 레이어의 역할
- - 비즈니스 로직의 중앙화 : 서비스 레이어는 여러 DAO 메소드를 조합하고 필요한 비즈니스 규칙을 적용하여 데이터를 처리한다.
- - 데이터 액세스 로직과의 분리 : 데이터 액세스 로직과 비즈니스 로직을 분리하여, 각각의 변경이 서로에게 미치는 영향을 최소화한다.
- - 재사용성과 유지보수성 향상 : 서비스 레이어를 통해 비즈니스 로직을 중앙화함으로써, 코드의 재사용성을 높이고 유지보수를 용이하게 한다.
- -트랜잭션 관리 : 서비스 레이어는 종종 여러 DAO 메소드 호출을 하나의 트랜잭션으로 묶는 역할을 담당한다.
실제 예시를 들어 이해해 보자
만약 사용자와 주문 테이블이 외래키 관계에 있고 사용자가 주문을 취소하는 경우 두 테이블 모두 업데이트해야 하는 상황이 왔다.
public interface UserDAO {
void updateUser(User user);
public interface OrderDAO {
void updateOrder(Order order);
}
여기서
만약 트랜잭션 처리를 하지 않고 그냥 내보내게 되면
유저 테이블에선 처리가 됬으나
오더 테이블에는 그대로 있는 경우가 생길 수 있다.
그래서 이렇게 한번에 처리가 되야되는 서비스들을 트랜잭션처리를 하게 됬다.
public class UserService {
@Autowired
private UserDAO userDAO;
@Autowired
private OrderDAO orderDAO;
// 사용자의 주문 취소 처리
@Transactional
public void cancelOrder(int userId, int orderId) {
// 주문 정보 조회 및 상태 업데이트
Order order = orderDAO.getOrderById(orderId);
order.setStatus("Cancelled");
orderDAO.updateOrder(order);
// 사용자 정보 조회 및 업데이트
User user = userDAO.getUserById(userId);
user.setNumberOfCancelledOrders(user.getNumberOfCancelledOrders() + 1);
userDAO.updateUser(user);
}
}
이런 식으로 트랜잭션 어노테이션을 달면 두 데이터베이스 작업이 모두 성공적으로 완료되거나, 하나라도 실패할 경우
전체 작업이 롤백되도록 보장한다.
그리고 유저 서비스 클래스는 UserDAO와 OrderDAO를 사용하여 주문 취소와 관련된 비즈니스 로직을 처리하고 있다.
이는 데이터 액세스 로직이 DAO에 숨겨져 있으며, 서비스 레이어가 복잡한 비즈니스 로직을 캡슐화하고 있다는걸 말한다.
서비스 레이어란
서비스 레이어는 비즈니스 로직을 캡슐화하고 데이터 액세스 레이어와 프레젠테이션 레이어 사이에서 중재자 역할을 한다.
서비스 레이어는 애플리케이 핵심 비즈니스 로직을 구현하고, 데이터의 일관성과 무결성을 유지하는 중요한 기능을 수행한다.
서비스 레이어의 역할
- - 비즈니스 로직의 중앙화 : 서비스 레이어는 여러 DAO 메소드를 조합하고 필요한 비즈니스 규칙을 적용하여 데이터를 처리한다.
- - 데이터 액세스 로직과의 분리 : 데이터 액세스 로직과 비즈니스 로직을 분리하여, 각각의 변경이 서로에게 미치는 영향을 최소화한다.
- - 재사용성과 유지보수성 향상 : 서비스 레이어를 통해 비즈니스 로직을 중앙화함으로써, 코드의 재사용성을 높이고 유지보수를 용이하게 한다.
- -트랜잭션 관리 : 서비스 레이어는 종종 여러 DAO 메소드 호출을 하나의 트랜잭션으로 묶는 역할을 담당한다.
실제 예시를 들어 이해해 보자
만약 사용자와 주문 테이블이 외래키 관계에 있고 사용자가 주문을 취소하는 경우 두 테이블 모두 업데이트해야 하는 상황이 왔다.
public interface UserDAO { void updateUser(User user); public interface OrderDAO { void updateOrder(Order order); }
여기서
만약 트랜잭션 처리를 하지 않고 그냥 내보내게 되면
유저 테이블에선 처리가 됬으나
오더 테이블에는 그대로 있는 경우가 생길 수 있다.
그래서 이렇게 한번에 처리가 되야되는 서비스들을 트랜잭션처리를 하게 됬다.
public class UserService { @Autowired private UserDAO userDAO; @Autowired private OrderDAO orderDAO; // 사용자의 주문 취소 처리 @Transactional public void cancelOrder(int userId, int orderId) { // 주문 정보 조회 및 상태 업데이트 Order order = orderDAO.getOrderById(orderId); order.setStatus("Cancelled"); orderDAO.updateOrder(order); // 사용자 정보 조회 및 업데이트 User user = userDAO.getUserById(userId); user.setNumberOfCancelledOrders(user.getNumberOfCancelledOrders() + 1); userDAO.updateUser(user); } }
이런 식으로 트랜잭션 어노테이션을 달면 두 데이터베이스 작업이 모두 성공적으로 완료되거나, 하나라도 실패할 경우
전체 작업이 롤백되도록 보장한다.
그리고 유저 서비스 클래스는 UserDAO와 OrderDAO를 사용하여 주문 취소와 관련된 비즈니스 로직을 처리하고 있다.
이는 데이터 액세스 로직이 DAO에 숨겨져 있으며, 서비스 레이어가 복잡한 비즈니스 로직을 캡슐화하고 있다는걸 말한다.