-
[MongoDB] 트랜잭션 및 Auditing 설정Kotlin 2021. 11. 1. 11:22
이번 시간에는 스프링 코틀린 프로젝트에서 MongoDB의 트랜잭션 및 Auditing 설정을 하는 방법에 대해서 알아보도록 하겠습니다.
우선 트랜잭션 설정을 하기 위한 전제 조건으로는 MongoDB의 경우 replicaSet 설정이 되어 있어야 트랜잭션 설정 시 예외 발생 없이 정상적으로 동작을 합니다.
replicaSet 설정의 경우 아래 2개 글을 참조하시면 됩니다.
[MongoDB] 맥북에 MongoDB 설치 및 replicaSet 설정
[MongoDB] Docker 이미지로 replicaSet 설정 된 MongoDB 구동
github 상에서도 spring-kotlin-mongodb 하위에 docker-compose 폴더 안에 docker-compose.yml 파일이 들어가 있기 때문에 해당 폴더로 이동해서 아래 명령어를 실행해주시면 됩니다.
$ cd ~/IdeaProjects/spring-kotlin-guides/spring-kotlin-mongodb/docker-compose $ docker-compose up -d
우선 접속하려는 MongoDB의 정보를 application.yml 파일에 설정합니다.
위에서 docker로 MongoDB를 구동시켰다면 MongoDB에 접속 후 guides라는 데이터베이스를 생성합니다.
그리고 해당 데이터베이스에 접속할 수 있는 정보를 application.yml 파일에 추가합니다.
spring: data: mongodb: uri: mongodb://localhost:27017/guides
설정을 진행하기 위해서 MongoConfig 클래스를 생성
- transactionManager()를 통해서 트랜잭션 빈을 생성
- MongoTransactionManager 생성 후 @Transactional 어노테이션을 통해서 트랜잭션 관리가 가능해집니다.
- @EnableMongoAuditing 어노테이션을 통해서 Auditing 기능을 사용할 것을 명시
import org.springframework.boot.autoconfigure.mongo.MongoProperties import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.data.mongodb.MongoDatabaseFactory import org.springframework.data.mongodb.MongoTransactionManager import org.springframework.data.mongodb.config.EnableMongoAuditing import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory @Configuration @EnableMongoAuditing class MongoConfig { @Bean @ConfigurationProperties("spring.data.mongodb") fun properties(): MongoProperties { return MongoProperties() } @Bean fun mongoClientDatabaseFactory(properties: MongoProperties): SimpleMongoClientDatabaseFactory { return SimpleMongoClientDatabaseFactory(properties.uri) } @Bean fun transactionManager(databaseFactory: MongoDatabaseFactory): MongoTransactionManager { return MongoTransactionManager(databaseFactory) } }
Auditing을 위한 BaseDocumentEntity 생성
도메인 Entity를 생성 시 BaseDocumentEntity를 상속 받았을 때 자동으로 Auditing 기능을 사용할 수 있도록 추상 클래스를 생성합니다.
설정 시 주의 사항은 @Version 어노테이션을 통해서 버전 속성을 명시해줘야 @CreatedBy와 @CreatedDate의 필드값에 Auditing 값이 설정됩니다.
@Version 어노테이션이 없을 경우 @LastModifiedBy와 @LastModifiedDate 필드의 값만 설정됩니다.
import org.springframework.data.annotation.* import java.time.LocalDateTime abstract class BaseDocumentEntity { @CreatedBy var createdBy: String?= null @CreatedDate var createdAt: LocalDateTime?= null @LastModifiedBy var lastModifiedBy: String?= null @LastModifiedDate var lastModifiedAt: LocalDateTime?= null @Version var version: Int?= null }
AuditorAware 설정
Audit을 진행하는 주체를 주입해주기 위해서 AuditorAware를 상속 받아서 설정을 진행합니다.
예제에서는 Auditor의 ID 타입을 String으로 설정하였고, 예시이기 때문에 "server"라는 문자열 상수를 리턴하고 있습니다.
스프링 시큐리티를 사용하고 있다면 스프링 시큐리티 Context에서 Auditor의 ID를 찾아서 설정을 해주시면 됩니다.
import org.springframework.data.domain.AuditorAware import org.springframework.stereotype.Component import java.util.* @Component class InheritanceAuditAware : AuditorAware<String> { override fun getCurrentAuditor(): Optional<String> { return Optional.of("server") } }
테스트용 도메인 Entity, Repository 생성
import com.kotlin.mongodb.common.BaseDocumentEntity import org.springframework.data.annotation.Id import org.springframework.data.mongodb.core.mapping.Document @Document("item") class Item( @Id var id: Long?= null, var name: String?= null, var description: String?= null, var instock: Int?= null ) : BaseDocumentEntity()
import com.kotlin.mongodb.item.entity.Item import org.springframework.data.mongodb.repository.MongoRepository interface ItemRepository : MongoRepository<Item, Long> { }
테스트 케이스 작성
트랜잭션 설정을 해놓았기 때문에 @Transactional 어노테이션을 통해서 테스트 종료 시 전체 트랜잭션이 롤백되는 것을 확인할 수 있습니다.
Auditing 기능을 통해서 Auditor와 Audit 시간이 정상적으로 입력된 것을 확인 할 수 있습니다.
@Transactional @SpringBootTest class ItemRepositoryTest( @Autowired val itemRepository: ItemRepository ) { @Test fun `Item 생성 테스트`() { // given val item = Item().apply { this.id = 1 this.name = "Apple Watch" this.description = "IPhone 연동 전자 시계" this.instock = 10 } // when val savedItem = itemRepository.save(item) // then assertThat(savedItem.createdBy).isEqualTo("server") assertThat(savedItem.createdAt).isNotNull assertThat(savedItem.lastModifiedBy).isEqualTo("server") assertThat(savedItem.lastModifiedAt).isNotNull } }
이상으로 스프링 코틀린 프로젝트에서 MongoDB 트랜잭션 설정 및 Auditing에 대해서 살펴보았습니다.
해당 소스 코드는 github에서 확인해볼 수 있습니다.
- transactionManager()를 통해서 트랜잭션 빈을 생성