Hello

31. 영속성 컨텍스트와 더티체킹

by 볼빵빵오춘기

모든 요청을 받으면 Controller에 모인다.

그러면 Controller에서 응답을 해준다.

요청을 받으면 isnert, update, delete, select를 한다.

User라는 테이블을 만들었는데 User테이블에 행이 3건이 있다.

그러면 JPA라는 영속성 컨텍스트라는 것이 있다.

 

만약에 insert 한다고 치면 컨트롤러에서 USer객체를 하나 만든다. 그러고나서 save를 한다.

그럼 이게 어디에 들어오냐면 영속성 컨텍스트안에 1차 캐쉬라고 있다.

1차 캐쉬에 뭐가있냐면 user객체가 만들어져서 쌓인다. 그 user 객체로 db에 쏙 집어넣는다.

예를들어 데이터가 3건이 있다치면 save()를 하게되면 db에 4가 쏙 들어가게 된다.

그러면 1차캐시에 user가 생겼는데 그것을 영속화 되었다고 한다.

영속화된 객체를 db에 밀어넣는것을 flash라고 한다.(프로그램에서는 flash가 버퍼를 비운다고 표현)

 

flash가 되면 JPA에 1차 캐시가 비어져아 한다고 생각이 드는데 비어지지않고 그대로 남아있는다.

 

그러면 내가 4번 데이터를 select한다고 하면 근데 4번데이터가 영속화되서 들고 있다한다면 굳이 DB에가서 select하지않고 영속성컨텍스트에가서 들고와서 조회를 해준다. ⇒ DB에 부화를 줄여준다.

 

이런 상황에서 내가 id 2번을 비번을 update를 하고 싶다면

2번 데이터베이스에서 select해서 2번객체를 영속성컨텍스트에 영속화를 시킨다.

 

그러고 나서 영속성컨텍스트에있는 2번객체를 update시키기 위해 Controller에 들고온다.

 

들고와서 영속화된 해당 오브젝트에 user의 값을 변경하고나서 변경된 값으로 변경하기 위해 save()를 호출하게 되면

 

변경할려는 password와 email 의 id값과 영속화된 user객체의 id를 비교해보니 같은 id를 갖고있다.

그러면 영속화된 객체 password =! 변경 password, 영속화된 객체 email =! 변경 email 상태이므로 영속성 컨텍스트에 있는 user의 객체를 update 시켜 값을 변경 password, email 값으로 바꿔준다.

영속성 컨텍스트에 있는 객체를 DB에 flash해서 넣으면 DB도 변경이 된다.

이게 save만 하면 자동으로 일어난다.

 

    @Transactional 
    @PutMapping("/dummy/user/{id}")
    public User updateUser(@PathVariable int id,@RequestBody User requestUser){
        System.out.println("id : "+id);
        System.out.println("password : "+requestUser.getPassword());
        System.out.println("email : "+requestUser.getEmail());

				// 여기서 영속화가된다.
        User user = userRepository.findById(id).orElseThrow(()->{ 
            return new IllegalArgumentException("수정에 실패하였습니다.");
        });

				// 영속화된 오브젝트의 값이 변경된다.
        user.setPassword(requestUser.getPassword());
        user.setEmail(requestUser.getEmail());



        // 더티 체킹
        return user;
    }
		// 따라서 영속화된 오브젝트에서 값이 변경됨으로써 자동으로 영속성컨텍스트에서는 아 값이 변경이 되었구나 인식을 하게된다. 그러면서 update문을 수행된다. 
		// 함수 종료시에 자동 commit이 됨.

⇒ @Transactional 을 붙여줌으로써 메서드가 시작될 때 @Transactional 이 시작되고 메소드가 끝날 때 같이 끝난다. 이 때 자동으로 commit이 된다.

 

 

정리하자면

더티체킹(Dirty Checking)이란

상태 변경 검사이다. 

JPA에서는 트랜잭션이 끝나는 시점에 변화가 있는 모든 엔티티 객체를 DB에 반영한다. 

그렇기 때문에 값을 변경한뒤, save 하지 않더라도 DB에 반영되는 것이다. 

이러한 상태 변경 검사의 대상은 영속성 컨텍스트가 관리하는 엔티티에만 적용된다. 

 

더티체킹(Dirty Checking)의 원리

  • 영속성 컨텍스트란 서버와 DB사이에 존재한다. 
  • JPA는 엔티티를 영속성 컨텍스트에 보관할 때, 최초 상태를 복사해서 저장해둔다.(일종의 스냅샷)
  • 트랜잭션이 끝나고 flush할 때 스냅샷과 현재 엔티티를 비교해 변경된 엔티티를 찾아낸다. 
  • JPA는 변경된 엔티티를 DB단에 반영하여 한 번에 쿼리문을 날려준다.

'강의 따라하기 > blog' 카테고리의 다른 글

33. Exception 처리하기  (0) 2024.01.02
32. 삭제하기 테스트  (0) 2024.01.02
30. update 테스트  (0) 2024.01.02
29. 전체 select 및 paging 테스트  (0) 2024.01.02
28. id로 select 테스트  (1) 2024.01.02

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기