레이어드 아키텍처(Layered Architecture) 란?

최준영·2021년 9월 30일
0

컨트롤러와 서비스


  • 쇼핑몰에서 게시판에서도 회원 정보를 보여주고, 상품 목록 보기에서도 회원 정보를 보여줘야 한다면, 해당 코드를 별도의 객체인 서비스로 구현하는 것이 좋다.
  • 서비스 객체는 보통 업무와 관련된 메서드를 가지고 있다. 이것들을 비즈니스 메서드라고 부른다.
  • 비지니스 메소드를 별도의 service 객체에서 구현하도록 하고 컨트롤러는 service 객체를 사용하도록 한다.

서비스 객체

  • 비즈니스 로직을 수행하는 메소드를 가지고 있는 객체를 서비스 객체라고 한다.
  • 보통 하나의 비지니스 로직은 하나의 로직으로 동작한다.

트랜잭션

  • 하나의 논리적인 작업을 의미한다.

트랜잭션의 특징

원자성 (Atomicity)

  • 전체가 성공하거나 전체가 실패하는 것을 의미한다.
  • 출금이라는 기능의 흐름이 다음과 같다고 생각해보자
    1. 잔액 조회
    2. 출금 금액이 잔액보다 작은지 검사
    3. 작다면 잔액을 출금액을 뺀 금액으로 수정한다.
    4. 언제, 어디서 출금했는지 정보를 기록한다.
    5. 사용자에게 출금한다.
  • 만약 중간에 오류가 발생한다면, 그동안의 작업을 모두 원래대로 복원을 해야한다. 이를 rollback이라고 한다.
  • 모두 성공했다면 정보를 반영해야 한다. 이를 commit이라고 한다.
  • 이렇게 rollback 하거나 commit을 하게 되면 하나의 트랜잭션 처리가 완료된다.

일관성 (Consistency)

  • 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다.
  • 트랜잭션이 진행되는 동안 데이터가 변경되더라도 처음에 트랜잭션을 진행하기 위해 참조한 데이터로 진행한다.
    • 이렇게 함으로써 각 사용자는 일관성 있는 데이터를 볼 수 있다.

독립성 (Isolation)

  • 둘 이상의 트랜잭션이 동시에 병행 실행되고 있는 경우에 어느 하나의 트랜잭션이라도 다른 트랜잭션의 연산에 끼어들 수 없다.
  • 하나의 특정 트랜잭션이 완료될 때까지, 다른 트랜잭션이 특정 트랜잭션의 결과를 참조할 수 없다.

지속성 (Durability)

  • 트랜잭션이 성공적으로 완료되었을 경우, 결과는 영구적으로 반영되어야 한다.

JDBC 프로그래밍에서 트랜잭션 처리 방법

  • DB에 연결된 후 Connection 객체의 setAutoCommit 메소드에 false를 파라미터로 지정한다.
    • setAutoCommit의 디폴트는 true로 되어있어서 입력, 수정, 삭제를 하면 별도로 commit 명령을 수행하지 않아도 바로 데이터베이스에 반영된다.
  • 입력, 수정, 삭제 sql이 실행을 한 후 모두 성공했을 경우 Connection이 가지고 있는 commit() 메소드를 호출한다.

@EnableTransactionManagement

  • Spring Java Config 파일에서 트랜잭션을 활성화 할 때 사용할 수있는 어노테이션이다.
  • Java Config를 사용하게 되면 PlatformTransactionManager 구현체를 모두 찾아서 그 중에 하나를 매핑해 사용한다.
  • 특정 트랜잭션 매니저를 사용하고자 한다면, TransactionManagementConfigurer를 Java Config 파일에서 구현하고 원하는 트랜잭션 매니저를 리턴하도록 한다.
  • 아니면, 특정 트랜잭션 매니저 객체를 생성시 @Primary 어노테이션을 지정한다.

서비스 객체에서 중복으로 호출되는 코드의 처리

  • 서비스 객체들마다 비즈니스 메서드를 가지고 있고, 이 하나의 비즈니스 메서드는 트랜잭션 단위로 보통 작업이 처리가 된다.
  • 하나의 트랜잭션에는 여러 개의 DB 작업이 수행될 수도 있다.
    이 때, 메서드마다 중복되는 기능을 호출하는 경우도 있는데, 이런 부분을 별도의 객체나 메서드로 분리해서 사용해야 한다.
  • Presentation Layer에서는 컨트롤러 객체가 동작을 한다.
    • 이 부분이 웹에서 보여진다.
    • 앱, window 등에서 보여지게 하려면 해당 계층만 바꿔주면 된다. 때문에 설정 파일들도 분리하는 것이 좋다.
  • Service Layer에서는 비즈니스 메서드를 가지고 있는 서비스 객체가 동작한다.
  • Repository Layer에서는 실제 데이터 베이스에 접근해서 데이터를 가져오는 일과 같은 것들만 수행한다.
    • 데이터 액세스 메소드를 별도의 Repository(Dao) 객체에서 구현하도록 하고 Service는 Repository 객체를 사용하도록 한다.

설정의 분리

  • Spring 설정 파일을 프레젠테이션 레이어쪽과 나머지를 분리할 수 있다.
  • web.xml 파일에서 프리젠테이션 레이어에 대한 스프링 설정을 DispatcherServlet이 읽도록 하고, 그 외의 설정은 ContextLoaderListener를 통해 읽도록 한다.
  • Dispatcher Servlet을 경우에 따라서 2개 이상 설정할 수 있는데, 이 경우에 각각의 dispatcherServlet의 ApplicationContext가 각각 독립적이기 때문에 각각의 설정 파일에서 생성한 빈을 서로 사용할 수 없다.
    • 같이 동시에 필요한 빈은 ContextLoaderListener를 사용함으로써 공통으로 사용할 수 있다.
  • ContextLoaderListener와 DispatcherServlet은 각각 ApplicationContext를 생성하는데, ContextLoaderListener가 생성하는 ApplicationContext가 root 컨텍스트가 되고 DispatcherServlet이 생성한 인스턴스는 root 컨텍스트를 부모로하는 자식 컨텍스트가 된다.
    • 자식 컨텍스트들은 root 컨텍스트의 설정 빈을 사용할 수 있다.
profile
do for me

0개의 댓글