Какая связь между Spring Entity Manager и Spring Data Repository?Почему очистка Spring Entity Manager влияет на используемую память, если я выполняю операции с репозиторием данных Spring?
Spring Data JpaRepository
имеет ссылку на EntityManager
и использует ее для реализации своих методов.Для фиксированных методов, составляющих JpaRepository
, вы можете найти реализации в SimpleRepository
Как [очистка] очистки EntityManager
влияет на другие операции чтения / записи, которые могут происходить во время пакетной обработкиОбработка?
EntityManager
является конструкцией JPA.Все управляемые ссылки связаны с одним EntityManager
.Это так, что реализация JPA узнает, когда объект изменяется, и, следовательно, нуждается в сохранении при следующем событии сброса.Для этого EntityManager
должен отслеживать все сущности, с которыми он сталкивается.В типичном веб-приложении это означает:
- вы загружаете некоторые объекты.
- изменяете их.
- может добавлять или удалять некоторые объекты
- flushлота и закройте
EntityManager
в конце запроса.
Так как только пара объектов вовлечена, хранение ссылки на все объекты не является большой проблемой.
В пакетной настройке вещи часто работают совсем иначе.Без особой мысли естественным будет следующее:
- вы загружаете некоторые объекты.
- изменяете их.
- может добавлять или удалять некоторые объекты.
- повторить тысячи или миллионы раз.
- в конце партии очистите лот и закройте
EntityManager
.
Таким образом, вы сохраняете многие тысячи или даже миллионы ссылок на объекты, которые во многих случаях не будутприкоснуться больше.Это оказывает давление на память и также влияет на производительность, когда EntityManager
обращается к своему списку ссылок на сущности.Такими операциями являются:
- Проверка для каждой загруженной и сохраняемой сущности, если на нее уже есть ссылка в
EntityManager
- Проверка того, какие сущности необходимо сохранить во время события сброса, и вывод всех оператороввыполнить в правильном порядке.
Но есть и преимущества EntityManager
и его кеша 1-го уровня (карта сущностей, которые он хранит): сущности загружаются только один раз.Если ваш пакет ссылается на некоторые уже существующие сущности (типичные «основные данные») снова и снова, он загружается не снова и снова, а только один раз за EntityManager
.Таким образом, вы, вероятно, также не хотите сбрасывать EntityManager
после каждой обработанной строки.
Как создать выделенные экземпляры Spring Entity Manager и Spring Data Repository?Сейчас я использую базовую автоматическую проводку.
Вы не делаете.Есть способы создания выделенных экземпляров.В конце концов, это просто код Java.Но вы действительно не хотите этого делать.Вместо этого просто используйте экземпляр репозитория sing, который генерируется для каждого типа.Он получает один прокси для EntityManager
.Фактический EntityManager
будет жить для транзакции.И получите обмен в начале транзакции внутри прокси, упомянутого выше.Это является частью Spring Scope Magic.
Вам нужно пометить ваши методы с помощью @Transactional
таким образом, чтобы транзакции оставались в разумных пределах.
Имеет ли смысл создание отдельного экземпляра Spring Entity Manager и Spring Data Repository для пакетной обработки?
Нет, я так не думаю.Это только усложняет ситуацию.