본문 바로가기

Spring

벌크연산시 주의할 점

728x90

벌크성 수정쿼리 test 코드

@Test
public void bulkUpdate() {
        //given
        memberRepository.save(new Member("member1", 10));
        memberRepository.save(new Member("member2", 19));
        memberRepository.save(new Member("member3", 20));
        memberRepository.save(new Member("member4", 21));
        memberRepository.save(new Member("member5", 40));

        //when
        int resultCount = memberRepository.bulkAgePlus(20);

        Member member = memberRepository.findByUsername("member5");
        
        //then
        assertThat(resultCount).isEqualTo(3);
        assertThat(member.getAge()).isEqualTo(41);
    }

1. 수정 쿼리 후 영속성컨텍스트를 초기화하지 않은 경우

 

@Modifying
@Query("update Member m set m.age = m.age+1 where m.age>=:age")
int bulkAgePlus(@Param("age") int age);

error문

벌크성 수정쿼리는 영속성컨텍스트를 거치지 않고 DB에 바로 수정쿼리를 날린다. 수정쿼리를 날린 후 영속성컨텍스트를 초기화하지 않았기 때문에 DB의 데이터값과 영속성 컨텍스트의 데이터값이 달라지는 경우가 생겨 오류가 발생한다.

 

2. 수정 쿼리후 영속성컨텍스트를 초기화 한 경우

@Modifying(clearAutomatically = true) // em.clear();
@Query("update Member m set m.age = m.age+1 where m.age>=:age")
int bulkAgePlus(@Param("age") int age);

clearAutomatically = true 속성을 이용하면 수정쿼리 후 자동으로 영속성 컨텍스트를 초기화해준다. 영속성 컨텍스트에 엔티티가 없는 상태에서 벌크 쿼리를 날리거나 부득이하게 영속성 컨텍스트에 엔티티가 있을 경우 벌크연산 직후 영속성 컨텍스트를 초기화 해주어야한다.

728x90