[Spring] MongoDB - MongoTemplate 과 Auditing
Spring 에서 JPA Auditing 을 사용해 자동으로 값을 넣어주는 기능을 잘 사용하고 있었다.
MongoDB 를 사용할 때도 Auditing 기능을 사용하고자 했는데
JPA 기반 Auditing 과 차이가 있었다.
Auditing 기능은 엔티티가 생성되거나 수정될 때 자동으로 특정 필드를 채워주는 기능이다. (createdAt, createdBy)
Auditing과 mongoTemplate의 독립성
Auditing은 repository 기반 데이터를 조작할 때만 자동으로 동작합니다.
하지만 mongoTemplate.updateFirst()는 쿼리 기반으로 작동하므로 @LastModifiedDate를 사용해도 자동으로 업데이트 되지 않는다.
Auditing 필드(createdAt, createdBy)가 업데이트되지 않으면 데이터 불일치가 발생할 수 있다.
따라서, mongoTemplate.updateFirst()를 사용할 때는 Auditing 필드를 수동으로 업데이트해야 하며
이를 명확하게 관리하면 데이터 꼬임을 방지할 수 있다.
Update update = new Update()
.set("someField", newValue)
.set("modifiedDate", LocalDateTime.now()); // Auditing 필드를 수동으로 설정
mongoTemplate.updateFirst(query, update, YourEntity.class);
중복 업데이트 시 문제
mongoTemplate.updateFirst()를 사용하면서 @LastModifiedDate를 수동으로 설정하면 Auditing 필드가 중복으로 업데이트되거나 잘못된 값이 들어갈 가능성이 있다.
예를 들어 여러 작업에서 동시에 modifiedDate를 갱신하는 경우, 동시성 문제가 발생할 수 있다.
repository를 사용하는 부분과 updateFirst()를 사용하는 부분이 혼재하면 데이터 일관성이 깨질 수 있고
updateFirst()는 데이터베이스 레벨에서 작동하므로 동기화되지 않을 수 있다.
따라서, Auditing이 필요한 작업은 save()를 통해 처리하고, 쿼리 기반 업데이트는 Auditing 필드를 명시적으로 업데이트한다.
동시성 및 트랜잭션 문제
mongoTemplate.updateFirst()는 쿼리 기반으로 특정 필드만 업데이트하므로 동시성 문제나 트랜잭션 경계가 명확하지 않을 때 데이터 꼬임이 발생할 수 있다.
repository로 처리되는 작업은 엔터티 기반으로 작동하지만, updateFirst()는 데이터베이스 레벨에서 작동하므로 동기화되지 않을 수 있다.
MongoDB는 기본적으로 트랜잭션이 필요한 작업이 아니므로, 데이터 설계와 동시성 제어를 철저히 관리해야 한다.
하지만 동시성을 보장해야 한다면 Transaction 사용도 잘 알아보고 사용하면 좋을 것 같다.