You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
'자바와 MySQL의 시간 정밀도 차이'로 인한 문제가 있을거라고는 생각도 못했다.
그리고 인터넷에 이와 관련된 정보도 많지 않아서 원인 파악도 어려웠다.
다른 개발자들은 이런 문제를 겪지 않는건가? 아니면 내가 뭔가를 잘못하고 있는건가? 🤔
자바 + MySQL로 개발한다면 한번쯤 겪을 수 있는 문제라 생각하는데,
전혀 알려지지 않은 문제라서 신기했다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
문제 상황
ci 를 도입하던 중, 기존 테스트 코드가 통과하지 않는 문제가 발생했다.
로컬에서는 발생하지 않지만, ci에서만 발생해서 상당히 당황스러웠다. 😳
➡️ 시간을 비교할 때 expected(= 엔티티)와 actual(=실제 조회된 값, dto)의 나노 세컨트가 달라서 발생한 오류였다.
문제 원인
자바의 시간을 나타내는 클래스들은 최대 9자리의 나노초를 나타낼 수 있다.
e.g.
LocalDateTime,Instant,OffsetDateTime,ZonedDateTimecf. ZonedDateTime은 LocalDateTime + 타임존 형식이다.
하지만 MySQL의 시간 타입은 최대 6자리의 마이크로초를 나타낼 수 있다.
따라서 어플리케이션에서 만든 ZonedDateTime은 9자리의 나노 초까지 나타냈는데,
이를 MySQL에 저장할 때는 6자리만 저장되었고,
이를 다시 조회하니 짤려진 6자리만 조회되었다.
당연하게도 이 두 값은 다르기 때문에 테스트가 실패했다.
테스트가 내 로컬에서는 통과하고, ci 환경에서는 실패하는 이유는 뭘까? 🤔
자바의 시간 클래스들은 '시스템의 시계에 의존'한다.
내 mac 환경에서는 6자리까지 나타내지만,
ci의 우분투 러너 환경에서는 9자리까지 나타낸다.
두 환경의 '시간 정밀도 차이'로 인해서 이런 문제가 발생했다.
문제 해결
처음에는 '어플리케이션에서 다뤄지는 모든 시간 클래스들이 정해진 정밀도를 가지게 할 방법'을 찾아봤다.
하지만 내가 못찾은 것인지.. 존재하지 않았다. 😓
그래서 createdAt과 updatedAt을 할당하는 코드에서 범위를 지정하도록 코드를 바꿨다.
AS-IS
this.createdAt = ZonedDateTime.now(ZoneId.of("UTC"));
TO-BE
this.createdAt = ZonedDateTime.now(ZoneId.of("UTC")).truncatedTo(MICROS);
여기서 MICROS는 '나노 초'가 아니라 '마이크로 초'까지만 저장하게 하는 단위이다.
느낀 점
'자바와 MySQL의 시간 정밀도 차이'로 인한 문제가 있을거라고는 생각도 못했다.
그리고 인터넷에 이와 관련된 정보도 많지 않아서 원인 파악도 어려웠다.
다른 개발자들은 이런 문제를 겪지 않는건가? 아니면 내가 뭔가를 잘못하고 있는건가? 🤔
자바 + MySQL로 개발한다면 한번쯤 겪을 수 있는 문제라 생각하는데,
전혀 알려지지 않은 문제라서 신기했다.
ref.
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html
https://dev.mysql.com/doc/refman/8.4/en/time.html
Beta Was this translation helpful? Give feedback.
All reactions