콘텐츠로 이동

2021 08 05

2021-08-05

em.flush(), em.clear()

  • 참고: https://apalsl.github.io/2019/11/14/SpringJpaFlushClear/
  • 하는 일: DB에 데이터를 반영하고, 영속성 컨텍스트 지움
  • springboot에서 persist(), flush(), clear() 가능 - 트랜잭션 시작되고 끝나기 직전가지 내가 날린 데이터는 영속성 컨텍스트에 저장
  • flush()하면 영속성 컨텍스트에 있는 데이터 DB까지 접근 시킴 - commit 되는 것 아님, 따라서 DB에 반영 안대! - 실제 어떤 쿼리 날리는지 확인할 수는 있음
  • clear()하면 영속성 컨텍스트에 저장한 데이터 지워버림 - DB에 저장된 데이터 지우는 것은 아님

saveAndFlush()

  • @Transactional있이 save() vs saveAndFlush() - 둘 모두 save/saveAndFlush 이후에 .setName() 한 것 "함수 종료시까지는" 반영안댐 - "함수 종료후에" 뚝딱 업데이트 댐
  • @Transactional있이 save() vs saveAndFlush() 후 set 여러번하기
    @Transactional
    public Member saveMember(MemberDTO memberDTO){
        Member member = Member.create(memberDTO);
        member = memberRepository.save(member); //INSERT QUERY 출력
        member.setName("TaeHyun");
        member = memberRepository.save(member); //QUERY 출력 X
        member.setName("TaeHyun2");
        member = memberRepository.save(member); //QUERY 출력 X
        member.setName("TaeHyun3");
        return member;
    }   //UPDATE QUERY 출력 & DB 뚝딱 변경
    
    @Transactional
    public Member saveMember(MemberDTO memberDTO){
    Member member = Member.create(memberDTO);
        member = memberRepository.saveAndFlush(member); //INSERT QUERY 출력
        member.setName("TaeHyun");
        member = memberRepository.saveAndFlush(member); //UPDATE QUERY 출력
        member.setName("TaeHyun2");
        member = memberRepository.saveAndFlush(member); //UPDATE QUERY 출력
        member.setName("TaeHyun3");
        return member;  
    }   //UPDATE QUERY 출력 & DB 뚝딱 변경
    
  • saveAndFlush()는 우리의 비즈니스로직에서 변경된 점을 사용해야하기 때문

영속성 컨텍스트

  • 참고 1: https://lollolzkk.tistory.com/27
  • 참고 2: https://stackoverflow.com/questions/14581865/hibernate-flush-and-commit
  • 영속성 컨텍스트 - Entity를 영구적으로 저장하는 환경 - Entity Manager를 하나 생성할 때 영속성 컨텍스트 하나가 생성됨 - 특징 1. 1차 캐시 - Map<@Id, Entity> 로 저장 2. 동일성 보장 - 싱글톤 3. 쓰기지연 수행 - 트랜잭션 범위 안에서 동작 - 트랜잭션 commit 전, 영속성 컨텍스트의 sql 저장소에 생성 쿼리 저장 - flush() 수행 후, 저장했던 생성쿼리를 DB에 반영 (DB 동기화) - 트랜잭션 commit 4. 변경 감지 - 영속성 컨텍스트에 있는 모든 엔티티를 스냅샷과 비교하여 수정된 엔티티 찾음 - 수정된 엔티티 확인하여 sql 저장소에 저장 - flush() 수행후 수정 쿼리 DB에 반영 - 트랜잭션 커밋
  • flush vs commit - flush는 영속성 컨텍스트에 있는 엔티티 정보를 DB에 동기화 - 하지만 commit 된건 아니라서 rollback 가능! - commit 된다면 롤백할 수 없는 상태!! - flush 왜 해야하지...? - 쓰기 지연 sql도 이게 메모리 차지한단 말이지? - 동기화를 우선해주고 쓰기지연 sql 비워줘야 해! - 아니면 메모리 터져!

@DirtiesContext의 동작과정?

빈을 Static으로?

@PostContruct, @PreDestory