Использовался ли кэш второго уровня Hibernate в вашем проекте?

Ответ

Да, мы использовали кэш второго уровня (L2 Cache) с провайдером Ehcache для снижения нагрузки на базу данных и повышения производительности read-heavy операций.

Зачем это нужно? Кэш второго уровня работает на уровне сессии (SessionFactory) и позволяет разделять кэшированные данные между разными сессиями Hibernate, что эффективно для часто читаемых и редко изменяемых сущностей.

Пример настройки в persistence.xml:

<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.region.factory_class" 
          value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>
<!-- Включение кэша для запросов -->
<property name="hibernate.cache.use_query_cache" value="true"/>

Пример аннотирования сущности:

@Entity
@Cacheable // JPA-аннотация
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Product {
    @Id
    private Long id;
    private String name;
    // ...
}

Важные моменты:

  • Необходимо выбирать правильную стратегию параллельного доступа (READ_ONLY, READ_WRITE, NONSTRICT_READ_WRITE).
  • Кэш запросов (query cache) требует осторожности, так как инвалидируется при изменении данных в затронутых таблицах.
  • Для распределенных систем часто используют Hazelcast или Infinispan вместо Ehcache.

Ответ 18+ 🔞

А, ну, кэш второго уровня, блядь! Это ж как банка сгущёнки в погребе на чёрный день, только для твоей базы данных, сука.

Ну, слушай сюда, а то я тебе сейчас объясню на пальцах, хули мы тут устроили. Представь, что твоя база — это такой вечно загруженный повар на кухне. Каждый раз, когда кто-то просит "дай мне пиццу 'Маргарита'", он бежит в холодильник, достаёт ингредиенты и начинает готовить с нуля. А заказов — овердохуища! Повар уже еле ноги волочет, блядь.

Так вот, L2 Cache — это мы поставили рядом с ним здоровенную, блядь, микроволновку. Повар один раз приготовил пиццу, положил туда, и теперь любой официант может её оттуда выхватить за секунду, не дергая повара за яйца. И главное — микроволновка-то общая на всю кухню! Все сессии Hibernate к ней имеют доступ. Красота, ёпта!

И как мы это, сука, настроили? В файлике persistence.xml наколдовали вот такие, блядь, заклинания:

<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.region.factory_class" 
          value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>
<!-- Включение кэша для запросов -->
<property name="hibernate.cache.use_query_cache" value="true"/>

А потом взяли сущность, например, Product, и навешали на неё, как новогоднюю ёлку, аннотации:

@Entity
@Cacheable // JPA-аннотация
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Product {
    @Id
    private Long id;
    private String name;
    // ...
}

Но тут, сука, есть подводные грабли, на которые можно влететь, как слепой крот в гравийную яму:

  1. Стратегию параллельного доступа надо выбирать с умом, а не тыкать пальцем в небо. READ_ONLY — если данные вообще не меняются (типа справочников). READ_WRITE — если меняются, но редко. Выбрал не ту — получишь глюки и рассинхрон, пиздец полный.
  2. Кэш запросов (query cache) — штука мощная, но капризная, как мартышлюшка в зоопарке. Изменил что-то в таблице — и всё, надо весь кэш этого запроса сбрасывать, иначе будут одни мудаки с устаревшими данными ходить.
  3. Если у тебя система не одна тачка, а целая куча серверов, то Ehcache может не потянуть. Тут уже надо смотреть в сторону всяких Hazelcast или Infinispan — они для таких, блядь, распределённых танцев с бубном заточены.

Короче, инструмент охуенный, производительность поднимает конкретно, но головой думать всё равно надо, а не просто копипастить настройки. Иначе будет не оптимизация, а один большой, блядь, баг-репорт.