Что такое dirty checking механизм Hibernate?

Введение

Persistence контекст ставит в очередь переходы между состояниями сущностей, которые транслируются в SQL выражения на этапе сброса (flush). Для управляемых сущностей, Hibernate автоматически обнаруживает входящие изменения и планирует операции SQL UPDATE за нас. Этот механизм называется автоматической «грязной» (dirty) проверкой.

Стратегия «грязной» проверки по умолчанию

По умолчанию Hibernate проверяет все свойства управляемых сущностей. Каждый раз, когда объект загружается, Hibernate делает дополнительные копии всех значений свойств сущностей. Во время flush, каждое свойство управляемой сущности сравнивается с копией, сделанной во время загрузки:

defaultflusheventflow1

Получается, что количество «грязных» проверок вычисляется по формуле:

latex где

n -количество управляемых сущностей

p -количество свойств каждой сущности

Даже если толкьо одно свойство одной сущности изменилось, Hibernate сверит все сущности. Для большого числа управляемых сущностей, дефолтный механизм «грязной» проверки может сильно нагрузить CPU и занять много памяти. Поскольку «слепок» сущностей, сделанный во время загрузки, хранится отдельно, persistence контексту требуется вдвое больше памяти, чем занимают все управляемые сущности.

 Инструментирование байт-кода

Более эффективный способ это отмечать «грязные» свойства после изменения значения. Аналогично оригинальной стратегии глубокого сравнения, в этом случае хорошая практикой является отделять структуру доменной модели от логики определения изменений. Механизм автоматического обнаружения изменения состояния сущности является сквозной функциональностью (аспектом), которая может быть связана или во время билда или в рантайме.

Класс сущности может быть присоединен с инструкциями на уровне байткода имлементирующими механизм «грязной» проверки.

Типы связывания

Улучшения байткода могут происходит в момент:

  • Создания билда

После того, как сущности Hibernate скомпилированы, инструмент создания билда (например Maven) вставит инструкции уровня байткода в каждый скомпилированный класс-сущность. Из-за того что классы изменяются во время создания билда, этот процесс не требует дополнительного времени в рантайме. Тестирование может быть проведено над расширенными версиями классов, так что актуальный production код будет валидирован до того, как этот проект будет собран.

  • Runtime

Runtime связывание может быть выполнено используя:

  • Java агента, выполнив улучшения байткода после загрузки класса сущности
  • Runtime контейнер (например, Spring), используя поддержку JDK Instrumentation.

В следующей статье я расскажу какие есть способы уменьшить количество сравнений при dirty checking.

Советую также посмотреть этот очень полезный доклад:

(Visited 1 171 times, 1 visits today)

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.