_

Always be tactful

MAIN/Java & Spring

JPA 프로젝트에서 타임스탬프 자동화를 위한 세 가지 전략

택트 2025. 6. 10. 06:10

타임스탬프

타임스탬프(Timestamp)는 어떤 사건이나 데이터가 발생한 정확한 시간을 기록한 값이다. 예를 들어 특정 데이터가 생성된 시점이나 수정된 시점을 저장하는 데 사용된다.

 

타임스탬프는 왜 남겨야 할까?

1. 데이터가 언제 생성되고 수정되었는지가 기록되기 때문에 변경 내역을 명확히 알 수 있다. 따라서 시스템 장애나 보안 사고 발생 시, 언제 어떤 변경이 있었는지를 추적하고 원인을 규명할 수 있다.

예를 들어, 은행 시스템에서 고객 계좌 정보가 잘못 변경되었다고 가정하자. 타임스탬프가 남아 있다면 누가 언제 계좌 정보를 수정했는지 정확히 알 수 있고, 문제가 발생한 시점을 추적하고 원인을 파악해 빠른 대응이 가능하다. 단순히 기록을 넘어 실시간 문제 대응 및 복구 작업의 도구로 활용될 수 있다. (Ex. 자동화된 롤백, 감사 로그 분석, 알림 시스템과 연동되어 장애 상황 해결)

 

2. 비즈니스 로직을 지원하기도 한다. 데이터의 최신성을 판단하거나 유효기간을 계산하는 등 서비스 핵심 기능 구현에 활용한다.

예를 들어, 온라인 쇼핑몰에서 할인 쿠폰의 유효기간을 관리한다고 가정하자. 타임스탬프가 있으면 쿠폰이 언제 발급됐고, 언제 만료되는지 정확하게 확인할 수 있다. 이 정보를 바탕으로 만료된 쿠폰은 자동으로 사용 불가능 처리하거나, 유효한 쿠폰만 고객에게 적용하는 로직을 구현할 수 있다.

 

3. 사용자 행동, 데이터 생성 추이 등을 분석해 비즈니스 인사이트를 얻는 데 기여할 수 있다.

예를 들어, 뉴스 사이트에서 각 기사가 언제 생성됐는지 기록된 타임스탬프가 있다면 운영팀은 특정 기간 동안의 어떤 주제의 기사가 많이 작성되었는지, 또는 사용자가 언제 가장 많이 방문하는지 등을 분석할 수 있다. 이를 바탕으로 인기 콘텐츠를 파악하거나 트래픽이 높은 시간대에 맞춰 서버를 유동적으로 운영하는 비즈니스 전략을 세울 수도 있다. (*사실, 실무적으로는 트래픽 변화에 따라 서버 인스턴스 수를 자동으로 조절하는 오토스케일링 기능 정도는 이미 제공되고 있다.)

 

타임스탬프 자동화 전략

우리가 시간을 기록해야 하는 상황 속에서, 물론 방법이야 훨씬 다양하겠지만 크게 세 가지 정도 분류할 수 있다.

  1. 직접 시계를 보고 시간을 적는다.
  2. 스마트워치가 자동으로 시간을 기록한다.
  3. 건물 출입 시스템이 자동으로 기록한다.

비유를 이렇게 했지만 조금 더 개발자스럽게 말하자면, 애플리케이션(JPA), 애플리케이션(Spring), DB로 계층을 나눈 것인데, 지금부터 하나씩 알아보자.

 

@PrePersist에서 now() 호출하기

직접 시계를 보고 시간을 적는 건, 개발자가 명시적으로 시간을 기록하는 @PrePersist 방식이다. 

@Column(nullable = false, updatable = false)
private LocalDateTime createdAt;

@PrePersist
protected void onCreate() {
    this.createdAt = LocalDateTime.now();
}

이 방식은 엔티티 클래스 내에 PrePersist 메서드를 정의해서, 해당 엔티티가 영속화(Persist)되기 직전에 직접 createdAt = LocalDateTime.now()와 같이 값을 지정한다. 장점이라고 한다면 개발자가 직접 시간 값을 넣어야 하므로, 명시적 호출에 따른 개발자의 통제가 가능한 셈이다. 사실상 자동화라고 보기 어려우며 반복 작업 가능성이 높다.

단, 테스트 코드나 모킹 상황에서 시간 값을 조작하거나 고정하기에는 타 전략들에 비해 비교적 쉬울 수 있다.

 

@CreatedDate 사용하기

스마트워치가 자동으로 시간을 기록하는 건, Spring Data JPA가 시간 값을 자동으로 기록하는 방식이다.

@CreatedDate
@Column(nullable = false, updatable = false)
private LocalDateTime createdAt;

엔티티 클래스 필드에 @CreatedDate을 붙이면, 영속화 시점에 Spring Data JPA가 자동으로 현재 시간을 주입한다. 이때 주의할 점은 @EnableJpaAuditing과 AuditorAware 설정이 선행되어야 한다는 점이다.

 

일관된 시간 기록을 보장하며, 애플리케이션 레벨에서 자동화된 타임스탬프 처리가 가능하다는 장점이 있다. 단, JPA에 의존하므로 영속성 컨텍스트를 통해 동작하는 구조이기 때문에, 직접 값을 지정하거나 외부에서 주입하기엔 제한이 있다.

 

DB Default 값으로 자동 기록하기

건물 출입 시스템이 자동으로 기록하는 건, 데이터베이스에 DEFAULT CURRENT_TIMESTAMP를 설정하는 방식이다.

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

DB 계층에서 설정하여, 애플리케이션이 따로 신경 쓰지 않아도 생성 시점의 시간이 자동으로 기록된다. 위처럼 설정된 컬럼은 INSERT 시 값이 비어 있으면 DB가 자동으로 현재 시간을 채워주게 된다.

 

애플리케이션 레벨 로직에 전혀 의존하지 않기 때문에, 데이터 일관성과 무결성 유지에 탁월하며, 비 JPA 환경에서도 잘 작동한다는 이점이 있다. 하지만 JPA가 이 값을 인식하지 못할 가능성이 있기 때문에 insertable = false, updatable = false 설정을 통해 컬럼에 값을 직접 쓰지 않도록 명시해 주는 것이 일반적이다.

@Column(name = "created_at", insertable = false, updatable = false)
private LocalDateTime createdAt;
굳이 단점이라고 한다면 시간 포맷과 타임존 일관성은 DB 설정에 따라 다를 수도 있다는 점이다.

비전공자가 학습을 위해 기록하는 블로그입니다.

틀린 정보가 있다면 댓글 남겨주세요!