ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring delete 메소드 주의사항
    Spring 2023. 2. 14. 22:33

    Delete 쿼리 종류

    TL;DR

    • 속도 측면에서는 deleteAllInBatch() 가 가장 빠르다.
    • test 코드를 제외하고는 deleteAllInBatch() 를 사용하지 말자

    설명

    delete(entity)

    해당 메서드는 CrudRepository 에 등록되어 있는 메서드 입니다. 엔티티를 파라미터로 받아 해당 엔티티를 삭제합니다.

    deleteAll()

    해당 메서드는 CrudRepository 에 등록되어 있는 메서드로 해당 레포지토리에서 관리 되는 모든 entity 를 삭제합니다.

    deleteAllInBatch()

    해당 메서드는 JpaRepository 에 등록되어 있는 메서드로 모든 entity 를 한번의 함수 실행으로 삭제합니다.

    예시

    코드의 예시로 설명해보겠습니다.

    예시로 다룰 엔티티는 Member 로 다음과 같습니다.

    @Where(clause = "deleted_at is null")
    @SQLDelete(sql = "update member set deleted_at = now() where id = ?")
    @Entity
    class Member(
        @Column(name = "name")
        val name: String,
    ) {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private val id: Long? = null
    ​
        @Column(name = "deleted_at")
        private val deletedAt: String? = null
    }
    @SpringBootTest
    @TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
    class MemberRepositoryTest(
        val memberRepository: MemberRepository,
    ) {
        @Test
        @DisplayName("멤버 삭제")
        fun deleteMember() {
            println("---------------------MemberSave START---------------------")
            val member = memberRepository.save(MemberFactory.of("test"))
            val member2 = memberRepository.save(MemberFactory.of("test"))
            val member3 = memberRepository.save(MemberFactory.of("test"))
            println("---------------------MemberSave END---------------------")
    ​
            println("---------------------Member DELETE START---------------------")
            memberRepository.delete(member)
            println("---------------------Member DELETE END---------------------")
    ​
            println("---------------------Member DELETE ALL START---------------------")
            memberRepository.deleteAll()
            println("---------------------Member DELETE ALL END---------------------")
    ​
            println("---------------------Member DELETE ALL IN BATCH START---------------------")
            memberRepository.deleteAllInBatch()
            println("---------------------Member DELETE ALL IN BATCH END---------------------")
        }
    }
    ---------------------MemberSave START---------------------
    Hibernate: 
        insert 
        into
            member
            (deleted_at, name) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            member
            (deleted_at, name) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            member
            (deleted_at, name) 
        values
            (?, ?)
    ---------------------MemberSave END---------------------
    ​
    ​
    ​
    ---------------------Member DELETE START---------------------
    Hibernate: 
        select
            member0_.id as id1_0_0_,
            member0_.deleted_at as deleted_2_0_0_,
            member0_.name as name3_0_0_ 
        from
            member member0_ 
        where
            member0_.id=? 
            and (
                member0_.deleted_at is null
            )
    Hibernate: 
        update
            member 
        set
            deleted_at = now() 
        where
            id = ?
    ---------------------Member DELETE END---------------------
    ​
    ​
    ​
    ---------------------Member DELETE ALL START---------------------
    Hibernate: 
        select
            member0_.id as id1_0_,
            member0_.deleted_at as deleted_2_0_,
            member0_.name as name3_0_ 
        from
            member member0_ 
        where
            (
                member0_.deleted_at is null
            )
    Hibernate: 
        update
            member 
        set
            deleted_at = now() 
        where
            id = ?
    Hibernate: 
        update
            member 
        set
            deleted_at = now() 
        where
            id = ?
    ---------------------Member DELETE ALL END---------------------
    ​
    ​
    ​
    ---------------------Member DELETE ALL IN BATCH START---------------------
    Hibernate: 
        delete 
        from
            member
    ---------------------Member DELETE ALL IN BATCH END---------------------
    ​

    코드의 결과를 살펴보면 delete(entity) 와 deleteAll() 는 soft delete 가 잘 작동하는 것을 확인할 수 있습니다. 또한 deleteAll() 은 하나의 레코드마다 하나의 update 쿼리가 생성되는것을 확인할 수 있습니다. 하지만 deleteAllInBatch() 는 모든 레코드는 hard delete 하는것을 확인할 수 있습니다.

    따라서 속도를 위해 deleteAllInBatch() 를 사용할 수 있지만 비즈니스 로직에서 쓰는것은 hard delete 할 일이 아닌 이상 매우 경계하면서 사용해야 합니다.

    'Spring' 카테고리의 다른 글

    Kotlin 에서 Spring 으로 테스트할 때 주의사항  (0) 2023.02.14
    Spring Bean  (0) 2022.07.25
    Spring에 비해 SpringBoot 가 가지는 특징  (0) 2022.07.03
    Filter 와 Interceptor 의 차이  (0) 2022.06.26
    @Transaction(readOnly = True)  (0) 2022.05.08

    댓글