일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- @EntityListeners
- getEntityGraph
- sendFractionalSeconds
- +9:00
- load order
- 오블완
- 운동해서 광명찾자
- NamedEntityGraph
- RootGraph
- EmbeddedId
- 1*1000
- @CreateDate
- https
- deserializer
- yml
- createEntityGraph
- mysql =
- mysql equal null
- apatch poi
- spring boot
- fractional seconds
- 버전 문자열 비교
- Protecle
- MYSQL
- pooled-lo
- mysql not equal null
- AuditingEntityListener
- getDateCellValue
- MSSQL
- 티스토리챌린지
- Today
- Total
Hello
[MSSQL] order by 정렬 기준의 데이터가 유니크 하지 않을 때 본문
팀에서 운영되고 있던 스케줄러가 동작하지 않는 다는 이슈를 전달 받아 확인해 보니 실행 중 DuplicateKeyException이 발생해 마무리되지 않고 종료된 것을 확인했다.
타 팀에서 우리 팀 스케줄러를 위한 테이블에 데이터를 넣어주는 작업을 진행 했고, qa에 이슈가 없어 real에 반영을 했는데 우리 팀 스케줄러 실행 시 에러가 발생했다.
데이터를 확인해보니 중복 된 데이터는 존재하지 않아 위 이슈가 발생한 것이 의아했다.
스케줄러 동작 과정은 아래와 같다.
1. 스케줄에 맞는 데이터 확인
2. 있을 경우
2-1. id값을 1000건 씩 조회
2-2. 이벤트 테이블에 id 저장
2-3. 이벤트 기간 테이블에 기간 변경
...id가 없을 때 까지 반복
3. 없을 경우 종료
2-2를 처리 하는 도중 DuplicateKeyException이 발생한 것을 확인 할 수 있었다.
2-1에서 사용하는 쿼리에서 중복 데이터를 조회 될 수 있는지 의심이 들어 dba 분에게 문의를 하고 같이 확인을 해보니 중복된 id가 반환 될 수 있는 것을 알게 되었다.
쿼리 실행 시 결과가 달라지는 것을 확인할 수 있었다.
다른 scheduleNo의 값을 조회해 보았을 때 regDate는 나노초 혹은 초단위로 다른 값이 들어가 있어서 정렬이 가능해 DuplicateKeyException이 발생하지 않았던 것이다. 타 팀에서 등록한 데이터에서 regDate를 동일하게 저장되어 구분 할 수 없었던 것이었다.
나는 order by에 사용된 컬럼으로 동일한 값이 나오면 pk 기준으로 정렬을 해줄 것이라고 예상했으나, 아니었다 order by에 사용된 컬럼으로만 정렬이 되었다!
근데 위 내용 또한 틀렷다. 해당 테이블에서 regDate 컬럼이 인덱스로 잡혀있지 않았던 것이다!
인덱스가 잡혀있는 scheduleNo 컬럼으로 정렬을 했을 경우 regDate와 동일하게 전체 같은 중복인데 결과 값은 순서를 보장했다.
결과적으로 인덱스가 없는 컬럼으로 정렬을 시도했기 때문에 정렬 순서를 보장 받지 못하여 일관된 결과 값을 리턴하지 않아 중복된 값이 조회되어 이벤트 테이블에 id 저장할 때 에러가 발생한 것이다!!
수정된 쿼리
order by
regDate desc offset 0 rows fetch next 1000 rows only
->
seq desc offset 0 rows fetch next 1000 rows only
or
scheduleNo desc offset 0 rows fetch next 1000 rows only
offset에서 사용하는 컬럼을 변경해 문제를 해결했다. 끝-
'DB' 카테고리의 다른 글
[MySQL] Charset과 Collation개념 및 조합 (0) | 2024.08.02 |
---|---|
[MySql] SQLException: Zero date value prohibited (0) | 2024.05.31 |
[MySQL|Connector/J] 시간대를 포함한 시간데이터 처리 (0) | 2024.02.08 |
[MySQL] not equal 검색 null 제외 (0) | 2023.12.19 |
[SQL SERVER] limitation of 2100 items for parameters (0) | 2023.09.22 |