findAll로 다 가져와서 앱에서 필터링? 아니면 쿼리 WHERE절에서 필터링? 어디서 관리하는게 더 나은가?

PagingItemReader 같이 offset 기반으로 분할해서 읽어오는 경우, 일단 다 가져와서 앱에서 필터링하게 되면 update로 인한 offset이 틀어짐이 발생 할 수 있다.

  • 전제
    • 작업 A1 read 대상 항목 : complete=n & type=A
    • 작업 B1 read 대상 항목 : complete=n & type=B
    • 작업 A1, B1에서는 read 대상 항목을 임시 테이블에 적재
    • 작업 A2, B2에서는 임시 테이블에서 대상 가져와 complete=y로 update
    • 작업 {}1, {}2는 다른 Step으로 되어 있음. (Chunk 단위 처리 아님)
      • 같은 Step으로 구성하고 read[complete=n] - update[complete=y] 하게 되면 chunk 단위 처리 때문에 단독 실행해도 offset이 틀어짐.
  • 상황 1 : PagingItemReader 쿼리가 complete=n인 항목들을 chunk 단위로 가져오고, type filtering은 앱에서 수행 (다른 타입이면 버린다)
    • 작업 A2가 처리 완료한 대상을 update 하고 있을 때, 작업 B1이 read 하고 있다면 complete=n인 항목의 개수가 달라지므로 offset이 틀어진다.
  • 상황 2 : PagingItemReader 쿼리가 complete=n & type={}인 항목들을 chunk 단위로 가져옴
    • 작업 A2가 처리 완료한 대상을 update 하는 것은 type=A인 항목들 뿐이고, 작업 B1는 애초부터 type=B로 읽고 있기 때문에 offset이 틀어지지 않는다.

 

JPA, Spring Data JDBC에서는 어떻게 처리하고 있나?

  • JPA, Spring Data JDBC 기본적인 조건 명시는 `` findTargetByXAndByY`` 방식인데, 조건이 여러개가 되는 경우는?
  • JPA의 경우, specification, criteria를 이용하면 `` findAll(searchCondition)`` 가능
  • Spring Data JDBC는 자체지원은 없으나 다른 library와 혼용 가능 (link)

어차피 이원화 될 수 밖에 없나? 쿼리랑 앱이랑...? 쿼리에서도 필터링하고 앱에서도 필터링하고?

 

장기적으로 봤을 때, 쿼리는 간단하게 가져가는게 좋다.

  • 비즈니스 로직은 앱단에 두고 쿼리는 간단하게 가는 것이 보통 변경에 유리한 구조이기 때문. 유지보수, 관리, 가독성 측면에서.
  • JPA 같은 ORM으로 마이그 할 여지가 있을 때 로직이 쿼리에 들어가 있으면 몹시 곤란하다.

 

기타 사례 나오면 추가

----

 

결론

어차피 쿼리에서 다 하거나, 앱에서 다 하거나 둘 중 하나로 선택 할 수가 없는 문제다.

[1. 쿼리에서 다 하거나 2. 앱에서 다 하거나 3. 쿼리 + 앱 이원화해서 하거나] 상황에 맞게 본인 판단으로 선택.

단, 너무 복잡하지 않게, 확장성 있게, 유지보수 하기 편한 방향으로 결정하면 된다.