728x90
한마디로
"Read와 CUD 트랜젝션을 분리할 수 있도록 어플리케이션 Model을 나누는 것"
기존의 무슨 문제가 있었나?
- 작업의 일부로 필요하지 않더라도 올바르게 업데이트해야 하는 추가 열 또는 속성과 같이 데이터의 읽기 및 쓰기 표현이 일치하지 않는 경우가 많습니다.
- 동일한 데이터 집합에서 작업을 병렬로 수행할 때 데이터 경합이 발생할 수 있습니다.
- 기존의 접근 방식은 데이터 저장소 및 데이터 액세스 계층의 로드와 정보를 검색하는 데 필요한 쿼리의 복잡성으로 인해 성능에 부정적인 영향을 미칠 수 있습니다.
- 보안 및 사용 권한 관리는 복잡해질 수 있습니다. 각 엔터티는 읽기 및 쓰기 작업이 모두 적용되므로 잘못된 컨텍스트에서 데이터를 노출할 수 있습니다.
어떤 효과가 발생하는가?
- 독립적인 크기 조정 : CQRS를 통해 읽기 및 쓰기 워크로드를 독립적으로 확장하고 더 적은 수의 잠금 경합이 발생할 수 있습니다.
- 최적화된 데이터 스키마 : 읽기 쪽에서는 쿼리에 최적화된 스키마를 사용하는 반면 쓰기 쪽에서는 업데이트에 최적화된 스키마를 사용할 수 있습니다.
- 보안 : 올바른 도메인 엔터티만 데이터에서 쓰기를 수행할 수 있는지 쉽게 확인할 수 있습니다.
- 관심사의 분리 : 읽기 및 쓰기 쪽을 구분하면 유지 가능하고 유연한 모델을 생성할 수 있습니다. 대부분의 복잡한 비즈니스 논리는 쓰기 모델로 이동합니다. 읽기 모델은 상대적으로 간단할 수 있습니다.
- 단순한 쿼리 : 읽기 데이터베이스에서 구체화된 뷰를 저장하여 쿼리할 때 애플리케이션은 복잡한 조인을 방지할 수 있습니다.
내가 짠 코드에도 Read와 CUD의 모델이 분할되지 않은 것이 있었다. 사용자를 Insert하는 곳에도, 사용자를 조회하는 곳에도 같은 memberVO 엔티티를 사용하다 보니 Login은 ID, Password만 비교하면 되는것을 굳이 불필요한 엔티티 공간을 할당하게 되어 메모리 리소스가 낭비된다.
@Repository("memberDAO")
public class MemberDAOImpl implements MemberDAO{
@Autowired
private SqlSession sqlSession;
@Override
public int insertMember(MemberVO memberVO) throws DataAccessException{
int result=sqlSession.insert("mapper.member.insertMember", memberVO);
return result;
}
@Override
public MemberVO loginById(MemberVO memberVO) throws DataAccessException{
MemberVO vo = sqlSession.selectOne("mapper.member.loginById",memberVO);
return vo;
}
이렇게 하나의 memberVO를 고집하게 되면 엔티티가 불필요하게 커져 각 트렌젝션의 효율이 떨어진다.
Member VO와 MemberData VO를 다르게 가져감
CQRS 예시
어플리케이션에서 Model(Entity)만 나눈 경우
Target Database까지 나눈 경우
'Programming > MSA' 카테고리의 다른 글
Domain Driven Design/Eric Evance - 2. Communication and the Use of Language (0) | 2022.07.19 |
---|---|
Domain Driven Design/Eric Evance - 1. 개요 ~ Crunching Knowledge (0) | 2022.07.19 |
MSA에 대한 기본개념 - 5. 회복성 (0) | 2022.06.12 |
MSA에 대한 기본개념 - 4. 서비스를 나눈뒤 상호참조, 통합 (0) | 2022.06.12 |
MSA에 대한 기본개념 - 3. Domain Driven Design 으로 가는 여정 (0) | 2022.06.10 |