Статьи

Высокопроизводительный JPA с GlassFish и Coherence — Часть 3

В этой третьей части моей серии из четырех статей я объясню стратегию номер два: использование Coherence с EclipseLink и GlassFish. Это все об использовании Coherence в качестве кэша второго уровня (L2) с EclipseLink.

Общий подход

Этот подход применяет сетку данных Coherence к приложениям JPA, которые полагаются на размещенные в базе данных данные, которые не могут быть полностью предварительно загружены в кэш Coherence. Некоторые причины, по которым он не может быть предварительно загружен, включают в себя чрезвычайно сложные запросы, которые превышают набор функций фильтров когерентности, обновления баз данных третьих сторон, которые создают устаревшие кэши, зависимость от собственных запросов SQL, хранимых процедур или триггеров и т. Д. Это не только опция для локальных кэшей L2, но с дополнительными настроенными экземплярами Coherence на разных узлах, вы также получаете кластерный JP2 L2-кэш.

подробности

Как и во многих кэшах, это оптимизация для чтения. Запросы первичного ключа пытаются сначала получить объекты из Coherence и, в случае неудачи, запросят базу данных, обновив Coherence результатами запроса. Запросы неосновного ключа выполняются к базе данных, а результаты сравниваются с Coherence, чтобы избежать затрат на создание объектов для кэшированных объектов. Новые запрашиваемые объекты вводятся в Coherence. Операции записи обновляют базу данных и, в случае успешного принятия, обновленные сущности помещаются в Coherence. Этот подход называется «Grid Cache» в документации Coherence.

Переместить это на практике

Начните с предыдущего поста в блоге и подготовьте свою среду , если вы еще этого не сделали. Есть одна вещь, которую нужно изменить. Вернитесь к GlassFish 3.0.1 / EclipseLink 2.0.1 для этого сценария, поскольку существует проблема с методом CacheKey.getKey (). 2.0.1 возвращает вектор , 2.2.0 просто возвращает объект . Увидев новый сервер Oracle GlassFish Server 3.1 с поддержкой ActiveCache, я ожидаю, что это будет исправлено в выпуске 3.7 Coherence. Но до тех пор, вы должны придерживаться старого GF или EclipseLink.

В любом случае, давайте создадим новый веб-проект с вашей любимой IDE (например, GridCacheExample). Добавьте необходимые библиотеки (coherence.jar, toplink-grid.jar и eclipselink.jar). Теперь давайте создадим наш класс сущности и добавим к нему дополнительную аннотацию @CacheInterceptor:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
...
 
import oracle.eclipselink.coherence.integrated.cache.CoherenceInterceptor;
import org.eclipse.persistence.annotations.CacheInterceptor;
 
...
 
@Entity
@CacheInterceptor(value = CoherenceInterceptor.class)
public class Employee implements Serializable {
 
...
 
}

Не забудьте добавить @GeneratedValue (Strategy = GenerationType.SEQUENCE), так как это необходимо в противоположность последнему примеру. После того, как это будет сделано, вы должны добавить конфигурацию согласованности в папку WEB-INF / classes. Вы можете начать с учебника ( Пример 2 ). (будьте осторожны, в нем есть опечатка… дублирующий тег </ backing-map-схема>). Сконфигурируйте свой файл persistence.xml так же, как и в обычном приложении на основе JPA.

01
02
03
04
05
06
07
08
09
10
11
<persistence-unit name="GridCacheExamplePU" transaction-type="JTA">
 
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/coherence</jta-data-source>
 
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.logging.level" value="FINE" />
</properties>
 
</persistence-unit>

Вот и все в принципе. Теперь вы можете проверить ваш новый кэш L2. Простой сервлет должен сделать свое дело:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class InsertServletPart3 extends HttpServlet {
 
@PersistenceUnit(unitName = "GridCacheExamplePU")
EntityManagerFactory emf;
 
@Resource
UserTransaction tx;
 
...
 
EntityManager em = emf.createEntityManager();
 
tx.begin();
 
// some loop magic
Employee employee = new Employee();
 
employee.setFirstName("Markus");
employee.setLastName("Eisele");
 
em.persist(employee);
 
// some loop magic end
tx.commit();
 
em.close();

Если вы посмотрите журнал, вы увидите что-то вроде этого:

1
2
3
4
5
FEIN: INSERT INTO EMPLOYEE (LASTNAME, FIRSTNAME) VALUES (?, ?)
 bind => [Eisele, Markus]
...
FEIN: Coherence(Employee)::Put: 1 value: net.eisele.coherence.entities.Employee[ id=1 ]
...

Что в основном говорит вам, что фактическая вставка базы данных выполняется EclipseLink, как вы привыкли. После этого вы можете видеть, что объект Employee помещается в Coherence Cache с именем Employee с ключом PK.

Если вы сейчас выполните запрос к базе данных

1
em.createQuery("select e from Employee e where e.lastName = :lastName").setParameter("lastName", "Eisele").getResultList();

вы видите следующее:

1
2
3
4
5
FEIN: SELECT ID, LASTNAME, FIRSTNAME FROM EMPLOYEE WHERE (LASTNAME = ?)
 bind => [Eisele]
FEIN: Coherence(Employee)::Get: 1 result: net.eisele.coherence.entities.Employee[ id=1 ]
FEIN: Coherence(Employee)::Put: 1 value: net.eisele.coherence.entities.Employee[ id=1 ]
...

Это говорит о том, что сам запрос выдается к базе данных, но результаты сверяются с Coherence, чтобы избежать создания объектов уже для кэшированных объектов. Новые запрашиваемые объекты вводятся в Coherence. Если вы выполняете простой запрос PK:

1
em.find(Employee.class, 1);

выход изменяется на:

1
FEIN: Coherence(Employee)::Get: 1 result: net.eisele.coherence.entities.Employee[ id=1 ]

и вы вообще не видите ни одного db-запроса. Вот и все ? Ваш кеш работает! Спасибо за чтение. Оставайтесь с нами для следующей части!

Дальнейшее чтение

Справка: высокопроизводительный JPA со GlassFish и Coherence — часть 3 от нашего партнера по JCG Маркуса Эйзела в блоге «Разработка корпоративного программного обеспечения на Java»

Статьи по Теме :