본문으로 건너뛰기

CQRS(명령 쿼리 책임 분리) 패턴

시스템은 크게 상태 변경과 조회 기능을 제공하는데요. 주문 취소, 결제 기능은 상태 변경에 해당되며, 주문서 조회, 사용자 조회 등이 조회에 해당됩니다.

✔️ 명령 쿼리 책임 분리 패턴 (Command Query Responsibility Segregation, CQRS)

상태를 변경하기 위한 명령을 위한 모델과 상태를 제공하는 조회(Query)를 위한 모델을 분리하는 패턴을 의미합니다. 예를 들어, Order라는 리소스를 Order(명령용), OrderData(조회용) 2개의 모델로 나누어서 관리할 수 있습니다. 이때 OrderData를 이용해서 표현 계층에 데이터를 출력하는 데 사용하고, 애플리케이션에서는 Order를 활용해 변경을 수행할 수 있습니다.

✔️ CQRS 패턴의 장단점은 뭘까? 🤔

CQRS 패턴을 따르면, 소프트웨어의 유지보수성을 높일 수 있습니다. 그리고, 모델별로 성능이나 요구사항에 맞는 데이터베이스나 데이터 접근 기술을 사용할 수 있습니다.

예를 들어, 명령 모델은 트랜잭션이 지원되는 RDB를 사용하고, 조회 모델은 조회 성능이 높은 NoSQL을 사용할 수 있습니다. 단, 해당 방식은 명령 모델의 변경을 조회 모델로 전파하여 동기화시켜야 할 필요가 있을 수 있습니다. 또 다른 예시로, 단일 데이터베이스의 테이블에 대해 CQRS 패턴을 사용한다고 가정했을 때는 명령 모델은 도메인 모델을 구현하는데 유리한 JPA를 사용하고, 조회 모델에 대해서는 SQL 데이터 조회에 유리한 MyBatis를 사용할 수 있습니다.

✅ JPA가 명령 모델에 유리한 이유

이유설명
도메인 주도 설계에 적합엔티티(Entity), 집합체(Aggregate), 리포지토리(Repository) 패턴 구현에 용이
변경 감지(Dirty Checking)객체의 필드 변경만으로도 자동으로 UPDATE SQL 생성
트랜잭션 처리 편리@Transactional로 복합적인 변경 작업을 안정적으로 처리 가능
비즈니스 로직 캡슐화 가능엔티티 내부에 도메인 메서드 및 제약 조건을 포함시켜 응집도 높은 설계 가능
높은 생산성SQL 작성 없이도 CRUD, 연관관계 관리 가능 → 반복 코드 감소
생애주기 및 상태 관리 기능 제공persist, merge, remove, flush 등 엔티티 상태 변화 관리가 자동화

✅ MyBatis가 조회 모델에 유리한 이유

이유설명
복잡한 SQL 작성 가능직접 SQL을 작성하여 JOIN, GROUP BY, 서브쿼리 등 복잡한 조회를 유연하게 처리 가능
성능 최적화 용이실행되는 쿼리를 명확히 제어할 수 있어 인덱스 활용, 튜닝이 용이함
원하는 컬럼만 조회 가능DTO로 필요한 필드만 선택적으로 매핑 가능 → 불필요한 데이터 로딩 방지
빠른 실행 속도JPA보다 내부 동작이 단순하여 쿼리 실행 속도가 빠름
N+1 문제 없음Lazy Loading 없이 모든 데이터 한 번에 가져오기 때문에 조회 성능 안정적
Mapper XML/어노테이션으로 명확한 쿼리 확인쿼리 로직이 코드와 분리되어 있어 유지보수 및 리뷰 시 가독성 높음

하지만, CQRS 패턴은 구현 코드가 많고, 더 많은 구현 기술이 필요하다는 점이 단점입니다. 따라서 단일 모델을 사용할 때 발생하는 복잡함 때문에 발생하는 구현 비용과 조회 전용 모델을 만들 때 발생하는 복잡함 때문에 발생하는 구현 비용을 비교해서 신중하게 도입을 결정해야 합니다.

Loading comments...