ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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에서 확인해볼 수 있습니다.

     

    댓글

Designed by Tistory.