배경
뉴스 API 를 요청하고 뉴스 상세 정보를 저장 하는 과정에서 뉴스 API를 여러 검색어로 요청 하다보니 중복되는 뉴스가 발생하여 같은 link 혹은 같은 제목으로 들어오는 뉴스는 제외 시켰지만, 중복되는 문제가 발생했습니다.
문제점
같은 데이터로 저장이되면, 뉴스를 보여주는 리스트 응답 데이터에 같은 데이터가 중복 되는 문제가 발생합니다.
1.
같은 데이터가 중복되어 저장되면 DB에 불필요한 데이터가 더 많이 저장되고 조회하는 경우에도 불필요한 데이터가 불러오기 때문에
해결방안
첫 번째 의심되는 상황 (검색어를 표시 하는 제목 불일치)
1.
저장된 데이터에서 jpa를 사용해 findByLnikOrTtile을 사용해 link가 같거나 title이 같으면 중복이 되지 않게 했지만 뉴스 API에서 데이터를 보내줄 때 title에 아래 사진과 같이 <b></b>태그안에 검색에 사용된 검색어를 감싸서 보내준다.
•
허깅페이스, <b>자바스크립트</b>용 기계학습 라이브러리 공개
•
"<b>알고리즘</b>도 꼼짝마"…대출비교플랫폼 상품 '저금리 순'으로
•
[Biz & Now] 삼성전자, AMD와 ‘차세대 엑시노스’ <b>개발</b> 협력
그래서 같은 제목이지만 첫번째는 ‘자바스크립’트로 검색되어서 허깅페이스, <b>자바스크립트</b>용 기계학습 라이브러리 공개 제목을 갖지만 검색어가 ‘자바’로 검색되면 허깅페이스, <b>자바</b>스크립트용 기계학습 라이브러리 공개 로 되어서 중복 처리가 안될 수 있다고 생각이 들었다.
두 번째 의심되는 상황(Transaction에 의해 DB에 반영되기전 데이터를 검색하여 중복검사가 안되는 문제)
2.
Transaction을 아래와 같이 설정을 해서 NewsApi가 전부 파싱되고 전부 저장이 되기 전까지 DB에 반영이 되지 않는다.
코드 예시
Transaction에 의해 아직 NewsApi가 DB에 적용되지 않았기 때문에 똑같은 Link, title로 되어있는 데이터가 들어와도 DB에서 조회가 되지 않기 때문에 중복으로 인식하지 않아서 생긴 문제라고 생각이 들었습니다.
여기서, 두 번째가 더 맞다고 생각 드는 부분이 있습니다.
트랜잭션 특징으로 원자성과 일관성을 갖고 있는데 각각의 특징은 이렇습니다.
•
원자성: 트랜잭션이 데이터베이스에 모두 반영되던가, 전혀 반영되지 않아야 한다.
•
일관성: 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다.
이 중에서도 일관성이 해당 문제가 발생된 원인이기도 한다고 생각 합니다. 일관성이라는 특징이 있기 때문에 트랜잭션이 진행되는 동안에 데이터베이스가 변경이 되더라도 업데이트된 데이터 베이스로 트랜잭션이 진행되는 것이 아니라, 처음에 트랜잭션을 진행 하기 위해 참조한 데이터베이스로 진행되기 때문에 뉴스 API를 저장하더라도 처음에 참조한 데이터 베이스에는 저장한 뉴스 API가 없기 때문에 그 다음 똑같은 뉴스가 검색되어 들어와도 중복 검사가 되지 않아 DB에 저장되고 전체 저장기능이 끝나면 중복된 데이터도 DB에 적용이 되는것이다. 물론 그 다음 NewsAPI가 동작하면 기존에 저장한 데이터는 중복 처리가 되지만 동작하는 시점에 동일한 데이터가 들어오면 중복 제거가 되지 않는 것입니다.
그래서 트랜잭션을 NewsAPI를 요청하고 요청된 데이터를 파싱하고 저장하는 최상단에 트랜잭션을 거는게 아니라 파싱하고 저장하는 부분에만 트랜잭션을 걸어 놓으면 중복 검사도 되고 하나의 데이터가 문제가 되면 트랜잭션처리도 되기 때문에 좋은 방안이라고 생각합니다.
( Option ) Alternative - 문제를 해결하지 못할 경우의 대안
이렇게 해도 문제가 해결되지 않는다면 당장에 문제를 해결하는 대안은 아래와 같습니다.
•
주기적으로 중복된 데이터를 삭제 하는 것입니다. 삭제할때는 아래와 같은 sql문으로 삭제를 합니다.
DELETE newsA FROM news newsA, news newsB
WHERE newsA.id > newsB.id AND (newsA.link = newsB.link OR newsA.title = newsB.title);
SQL
복사
•
또는 저장이 다 완료되는 시점에 위에 쿼리를 코드에 넣어서 삭제를 해줘도 좋을것 같습니다.
하지만 위와 같은 대안은 성능 문제는 해결을 하지 못하고 프론트에 중복된 데이터를 보여주지 않는 문제만 해결하기 때문에 반드시 다른 대안을 찾아야 한다고 생각합니다.