레이어드 아키텍처가 사용되는 이유
- 웹 페이지는 중복 개발되는 요소가 존재한다.
Controller에서 중복되는 부분을 처리하려면?
- 별도의 객체로 분리한다.
- 중복된 부분을 별도의 메서드로 분리한다.
- 예를 들어 쇼핑몰에서 게시판에서도 회원정보를 보여주고, 상품 목록 보기에서도 회원 정보를 보여줘야한다면 회원 정보를 읽어오는 코드는 어떻게 해야할까?
- 회원 정보를 읽어들이는 것만 별도의 객체로 만들고 게시판과 회원 정보 Controller가 이 객체를 이용.
Controller들이 중복적으로 호출하는 부분들은 별도의 객체인 Service로 구현하며, Service객체는 비즈니스 메서드를 갖는다. (업무와 관련된 메서드를 비즈니스 메서드라고 한다.)
서비스 객체란?
- 비즈니스 로직(Business logic)을 수행하는 메서드를 가지고 있는 객체를 서비스 객체라고 한다.
- 보통 하나의 비즈니스 로직은 하나의 트랜잭션으로 동작한다. (하나의 트랜잭션에는 여러개의 DB작업이 수행될 수 있다.)
- 서비스 객체에서 중복으로 호출되는 코드의 처리 : 데이터 엑세스 메소드를 별도의
Repository(Dao)객체에서 구현하도록 하고,Service는 Repository 객체를 사용.
트랜잭션이란?
- 트랜잭션은 하나의 논리적인 작업을 의미한다.
- 트랜잭션의 특징은 크게 4가지로 구분된다.
원자성 (Atomicity)일관성 (Consistency)독립성 (Isolation)지속성 (Durability)
원자성 (Atomicity)
- 전체가 성공하거나 전체가 실패하는 것을 의미한다.
- 예를 들어 "출금"이라는 기능의 흐름이 다음과 같다고 생각해보자.
- 잔액이 얼마인지 조회한다.
- 출금하려는 금액이 잔액보다 작은지 검사한다.
- 출금하려는 금액이 잔액보다 작다면 (잔액 - 출금액)으로 수정한다.
- 언제, 어디서 출금했는지 정보를 기록한다.
- 사용자에게 출금한다.
- 위의 작업이 4번에서 오류가 발생했다면 어떻게 될까? 4번에서 오류가 발생했다면, 앞의 작업들을 모두 원래대로 복원 시켜야한다. 이를
rollback이라고 한다. 5번까지 모두 성공했을 때만 정보를 모두 반영해야한다.
이를commit한다고 한다. 이렇게 rollback하거나 commit하게 되면 하나의 트랜잭션 처리가 완료된다. - 4번에서 오류가 발생했다면, 3번에서 잔액에서 출금액을 뺏는데, 사용자는 돈을 출금하지 못하고 작업이 종료되어서는 안된다. 즉, 잔액 조회부터 실제 사용자가 돈을 수령하기까지의 과정이 순차적으로 1, 2, 3, 4, 5로 번호가 매겨져있지만, 하나 하나를 다른일로 볼 수 없다. 1번부터 5번까지는 "출금"이라는 하나의 작업으로 묶여있다.
일관성 (Consistency)
- 일관성은 트랙잭션의 작업 처리 결과가 항상 일관성이 있어야 한다는 것이다. 트랜잭션이 진행되는 동안에 데이터가 변경 되더라도 업데이트된 데이터로 트랜잭션이 진행되는 것이 아니라, 처음에 트랜잭션을 진행하기 위해 참조한 데이터로 진행된다. 이렇게 함으로써 각 사용자는 일관성 있는 데이터를 볼 수 있을 것이다.
독립성 (Isolation)
- 독립성은 둘 이상의 트랜잭션이 동시에 병행 실행되고 있을 경우에 어느 하나의 트랜잭션이라도 다른 트랜잭션의 연산에 끼어들 수 없다. 하나의 특정 트랜잭션이 완료될 때까지, 다른 트랜잭션이 특정 트랜잭션의 결과를 참조할 수 없다.
- 데이터 베이스 사용자 A, B가 입력, 수정, 삭제와 같은 일들을 수행하고 있을 때, 사용자 A가 수행하고 있는 작업들이 commit을 하거나 rollback을 한다거나 트랜잭션을 완료하기 전까지는 사용자 B는 해당 부분에 대해서 알 수 없다.
- 예로, mysql console창을 두개 열어놓고 test를 해보면, 자동으로 commit 또는 rollback되지 않는한 console창 A에서 입력했던 내용이 B에는 적용되지 않는 것을 볼 수 있다.
지속성 (Durability)
- 지속성은 트랜잭션이 성공적으로 완료되었을 경우, 결과는 영구적으로 반영되어야 한다는 점이다.
JDBC 프로그래밍에서 트랜잭션 처리 방법
- DB에 연결된 후, Connection 객체의 setAutoCommit 메서드에 false를 파라미터로 지정한다. (default는 true)
- 입력, 수정, 삭제 SQL을 실행한 후, 모두 성공했을 경우 Connection이 가지고 있는 commit()메서드를 호출한다.
@EnableTransactionManagement
- Spring Java Config 파일에서 트랜잭션을 활성화 할 때 사용하는 어노테이션
- Java Config를 사용하게 되면 PlatformTransactionManager 구현체를 모두 찾아서 그 중에 하나를 매핑해 사용한다.
- 특정 트랜잭션 매니저를 사용하고자 한다면 TransactionManagementConfigurer를 Java Config 파일에서 구현하고 원하는 트랜잭션 매니저를 리턴하도록 한다.
- 아니면, 특정 트랜잭션 매니저 객체를 생성시 @Primary 어노테이션을 지정한다.
Presentation Layer에서는 Controller 객체가 동작.Service Layer에서는 Business method를 가지고 있는 Service 객체가 동작.- Service 객체는
Repository Layer에 있는 Dao 객체(데이터 베이스에 접근해서 데이터를 가져오는 등의 일들만 수행)를 사용. - Presentation Layer를 다른 걸로 바꿔도, Service Layer와 Repository Layer는 재사용할 수 있음.
- ex. Service Layer와 Repository Layer는 재사용하고, Presentation Layer만 바꿔주면 window programming이나 app으로 바꿀 수 있음.
- 재사용, 유지보수적인 면으로 봤을 때, Presentation Layer와 Service/Repository Layer는 설정 파일도 분리하는 것이 좋다.
설정의 분리
- Presentation Layer와 Service/Repository Layer의 Spring 설정 파일을 분리할 수 있다.
- web.xml 파일에서 Presentation Layer에 대한 Spring 설정은 DispatcherServlet이 읽도록 하고, 그 외의 설정은 ContextLoaderListener를 통해서 읽도록 한다.
- DispatcherServlet을 경우에 따라서 2개 이상 설정할 수 있는데, 이 경우에는 각각의 DispatcherServlet의 ApplicationContext가 각각 독립적이기 때문에 각각의 설정 파일에서 생성한 빈을 서로 사용할 수 없다.
- 위의 경우와 같이 동시에 필요한 빈은 ContextLoaderListener를 사용함으로써 공통으로 사용하게 할 수 있다.
- ContextLoaderListener와 DispatcherServlet은 각각 ApplicationContext를 생성하는데, ContextLoaderListener가 생성하는 ApplicationContext가 root컨텍스트가 되고 DispatcherServlet이 생성한 인스턴스는 root컨텍스트를 부모로 하는 컨텍스트가 된다. 참고로 자식 컨텍스트들은 root컨텍스트의 설정 빈을 사용할 수 있다.
참조 URL
'Java > Spring' 카테고리의 다른 글
Post 방식으로 데이터 전송시 한글이 깨지는 문제 (0) | 2020.06.30 |
---|---|
Spring Error (0) | 2020.06.30 |
Spring MVC가 지원하는 메소드 리턴 값 (0) | 2020.06.29 |
Spring MVC가 지원하는 메서드 Annotation (0) | 2020.06.29 |
Spring MVC가 지원하는 Controller 인수 타입 (0) | 2020.06.29 |