В нынешнем виде я использую bean-компонент с областью запроса JSF для выполнения всех моих операций CRUD. Как я уверен, вы, скорее всего, знаете, что Tomcat не обеспечивает постоянство, управляемое контейнером, поэтому в моем bean-компоненте запроса CRUD я использую EnityManagerFactory для получения кратности диспетчера объектов. Теперь о законности моего выбора использования bean-компонента с областью запроса для этой задачи, вероятно, он открыт для обсуждения (снова), но я пытался поместить его в контекст того, что я прочитал в статьях, которые вы дали мне ссылки к, в частности, первый и второй. Из того, что я понял, EclipseLink по умолчанию использует кеш уровня 2, в котором хранится кешированный объект. На сайте ExlipseLink Examples - JPA Caching говорится, что:
Общий кеш существует на время существования единицы сохраняемости ( EntityManagerFactory или server)
Разве это не заставляет мои кэшированные объекты жить в течение доли времени во время вызова, который выполняется для компонента запроса CRUD, потому что в момент уничтожения компонента, а вместе с ним и EntityManagerFactory, то же самое происходит и с кешем. Кроме того, последняя часть приведенного выше предложения EntityManagerFactory, или сервер, сбивает меня с толку. Что именно подразумевается под или сервером в этом контексте и как его контролировать. Если я использую аннотацию @Cache и установлю соответствующее значение атрибута expire, выполнит ли это задание и сохранит ли сущности, хранящиеся в кеше L2 серверов, независимо от того, был ли уничтожен мой EntityManagerFactory?
Я понимаю, что здесь нужно много внимания, и у каждого приложения есть свои особые требования. С моей точки зрения, настройка кеша L2, вероятно, является наиболее желательным (если не только на Tomcat) вариантом для оптимизации. Цитата из вашей первой ссылки:
Преимущества кэширования L2:
- избегает доступа к базе данных для уже загруженных сущностей
- быстрее для чтения часто используемых немодифицированных сущностей
Недостатки кэширования L2:
- потребление памяти для большого количества объектов
- устаревшие данные для обновленных объектов
- параллелизм для записи (исключение оптимистичной блокировки или пессимистическая блокировка)
- плохая масштабируемость для часто или одновременно обновляемых сущностей
Вы должны настроить кэширование L2 для сущностей, которые:
- читать часто
- модифицируется нечасто
- не критично если несвежий
Почти все вышеперечисленные пункты относятся к моему приложению. В основе этого, среди прочего, постоянное и неустанное чтение сущностей и отображение их на веб-сайте (приложение будет служить порталом для перечисления свойств). В приложении также создается небольшая корзина для покупок, но продаваемые продукты — это не материальные предметы, которые поступают в виде запасов, а услуги. В этом случае устаревшие объекты не являются проблемой, а также, я думаю, это не параллелизм, поскольку продукты (здесь услуги) никогда не будут записаны. Таким образом, объекты будут часто считываться и редко изменяться (и те, которые изменены, в любом случае не являются частью корзины, даже те, которые изменяются редко) и, следовательно, не критичны, если они устарели. Наконец, первые два пункта кажутся именно тем, что мне нужно, а именно предотвращение доступа к базе данных к уже загруженным объектам и быстрое чтение часто используемых немодифицированных объектов. Но есть один момент в недостатках, который меня все же немного беспокоит: потребление памяти для большого количества объектов. Разве это не похоже на мою первоначальную проблему?
В настоящее время я понимаю, что есть два варианта, только один из которых применим к моей ситуации:
Чтобы иметь возможность делегировать работу долгосрочного кэширования на слой сохраняемости, мне нужно иметь доступ к PersistenceContext и создать bean-компонент с областью действия сеанса и установить PersistenceContextType.EXTENDED. (эти параметры ко мне не относятся, нет доступа к PersistenceContext).
Настройте аннотацию L2 @Cache для сущностей или, как в варианте 1 выше, создайте bean-компонент с областью сеанса, который будет обрабатывать долгосрочное кэширование. Но разве они не возвращаются к моей первоначальной проблеме?
Мне очень хотелось бы услышать ваше мнение и посмотреть, что, по вашему мнению, могло бы быть разумным подходом к этому, или, возможно, как вы подходили к этому в своих предыдущих проектах. О, и еще одно, просто для подтверждения... при аннотировании объекта с помощью @Cache все связанные объекты будут кэшироваться вместе, поэтому мне не нужно аннотировать их все?
Опять же, все комментарии и указатели высоко ценятся.
Спасибо за ваш ответ .. когда вы говорите
В Tomcat лучше всего иметь статический менеджер, который удерживает EntityManagerFactory на время работы сервера.
Означает ли это, что я мог бы, например, объявить и инициализировать статическое поле EntityManagerFactory в приложении, предназначенном для последующего использования всеми bean-компонентами на протяжении всего жизненного цикла приложения?