-
Querydsl - 수정, 삭제 벌크 연산Spring/Querydsl 2022. 3. 25. 15:25728x90반응형
수정, 삭제 벌크 연산
여러개 수정, 삭제를 하면 데이터 수만큼 쿼리가 나가지만 벌크 연산을 사용하면 쿼리가 1번만 나간다. 따라서 여러개 수정, 삭제를 할 때는 벌크 연산을 사용하면 성능이 최적화된다.
@Test @DisplayName("벌크 연산") public void bulkUpdate() { long count = queryFactory .update(member) .set(member.username, "비회원") .where(member.age.lt(28)) .execute(); assertThat(count).isEqualTo(2); }
- count : 업데이트가 수행된 수
- execute() : 벌크 연산 수행
/* update Member member1 set member1.username = ?1 where member1.age < ?2 */ update member set username=? where age<?
참고로 해당 쿼리가 실행된 이후에는 해당 쿼리로 DB에는 값이 변경되지만 영속성 컨텍스트에는 값이 변경되지 않는다. 따라서 벌크 연산이 수행된 이후 같은 트랙잭션에서 변경된 값을 DB에서 가져오면 이미 영속성 컨텍스트에 해당 데이터가 이미 있기 때문에 영속성 컨텍스트 안에 변경되지 않은 데이터 값을 가져오는 문제가 발생한다.
따라서 벌크 연산 이후 같은 트랜잭션에서 다시 조회할 경우에는 em.flush()와 em.clear()를 해줘야 한다.
em.flush()와 em.clear()를 해줘야 하는 이유
벌크 연산 수행 전
memberDto = MemberDto(username=member1, age=10)
memberDto = MemberDto(username=member2, age=20)memberDto = MemberDto(username=member3, age=30)
memberDto = MemberDto(username=member4, age=40)
벌크 연산 수행 후(영속성 컨텍스트)
memberDto = MemberDto(username=member1, age=10)
memberDto = MemberDto(username=member2, age=20)memberDto = MemberDto(username=member3, age=30)
memberDto = MemberDto(username=member4, age=40)
벌크 연산 수행 후(DB)
memberDto = MemberDto(username=비회원, age=10)
memberDto = MemberDto(username=비회원, age=20)memberDto = MemberDto(username=member3, age=30)
memberDto = MemberDto(username=member4, age=40)
Member PK 1,2 조회
memberDto = MemberDto(username=member1, age=10)
memberDto = MemberDto(username=member2, age=20)→ DB에 가져오기 이전에 이미 영속성 컨텍스트에 해당 member가 있기 때문에 업데이트 된
member 값이 아닌 영속성 컨텍스트에 있는 업데이트가 실행 안된 값을 가져오게 된다.
728x90반응형'Spring > Querydsl' 카테고리의 다른 글
Querydsl - BooleanBuilder를 사용한 동적 쿼리와 성능 최적화 (0) 2022.03.26 Querydsl - Repository에서 Querydsl 사용하기 (0) 2022.03.26 Querydsl - where절을 이용한 동적 쿼리 (0) 2022.03.25 Querydsl - BooleanBuilder 이용한 동적 쿼리 (0) 2022.03.25 Querydsl - DTO로 조회하기 (0) 2022.03.25