최대 절전 모드 - 더티 체크

'더티 체크'란? 🤔



Hibernate는 '관리됨' 상태에 있는 엔티티 객체, 즉 지속성 컨텍스트에 추가된 엔티티 객체를 확인합니다. 엔터티 개체가 로드되면 해당 엔터티 개체의 모든 속성 복사본이 생성됩니다. 플러시 시간이라고 하는 동기화 시 엔터티 개체의 속성과 로드된 개체의 속성을 일치시켜 그 차이를 확인합니다. 이 프로세스를 "Hibernate Dirty Check"라고 합니다.

기본 엔터티부터 시작하겠습니다.

@Entity
@Table(name="comment")
@DynamicUpdate
public class CommentEntity{
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    private Long id;
    private String text;
    private String owner;
}


생성된 데이터를 EntityManager를 통해 데이터베이스에 유지합니다.

@Repository
@Transactional
public class CommentRepository {
    @Autowired
    EntityManager entityManager;

    public void save() {
        CommentEntity commentEntity= new CommentEntity();
        commentEntity.setText("my comment");
        commentEntity.setOwner("my owner");
        entityManager.persist(commentEntity);
    }
}


CommentRepository라는 빈의 저장 메소드를 호출하면 데이터베이스에 삽입됩니다. SQL 출력은 다음과 같습니다.

Hibernate: call next value for hibernate_sequence
Hibernate: insert into comment (id, text, owner) values (?, ?, ?)


동일한 데이터를 얻은 후에 데이터베이스에 동일한 데이터를 유지하려고 하면 어떻게 됩니까?

public void update() {
    CommentEntity commentEntity =
 entityManager.find(CommentEntity.class, 1l);
    entityManager.persist(commentEntity);
}


다음은 최대 절전 모드로 선택 쿼리만 수행하는 출력입니다.

Hibernate: select commententity0_.id as id1_1_0_, commententity0_.text 
as text2_1_0_, commententity0_.owner 
as owner3_1_0_ from comment commententity0_ 
where commententity0_.id=?


음... 객체의 속성을 변경하고 다시 지속하면 어떨까요?

public void update() {
    CommentEntity commentEntity = entityManager
                      .find(CommentEntity.class, 1l);
    commentEntity.setText("my other text");
    entityManager.persist(commentEntity);
}


이제 Hibernate는 선택 후 업데이트 작업을 적용합니다.

Hibernate: select commententity0_.id as id1_1_0_, 
commententity0_.text as text2_1_0_, commententity0_.owner 
as owner3_1_0_ from comment commententity0_ where commententity0_.id=?
Hibernate: update comment set text=? where id=?


Each time, Hibernate checks the properties of the entity object with the last loaded snapshot. If there is a change, it performs the update.
That's why this situation is called "Hibernate Dirty Check". In fact, it causes a performance loss.



해결책은 무엇인가? 🧠



엔터티가 로드되면 'Hibernate 더티 검사 메커니즘'은 현재 엔터티의 스냅샷을 로드된 엔터티와 비교하지만 업데이트하지 않을 때는 이 비교를 끌 수도 있습니다.

@Transactional(readOnly = true)


처리 중인 메서드를 readOnly = true로 표시하면 업데이트 작업이 없으므로 'Hibernate 더티 체크' 작업이 없습니다. 이것은 우리에게 성능을 제공합니다.

좋은 웹페이지 즐겨찾기