Original Article: Be Careful With Cache Managers
Author: Bozho's tech blog

Tenha cuidado com gerentes de cache

Se você estiver usando Spring e JPA, é muito provável que você utilize ehcache (ou outro provedor de cache). E você faz isso em dois cenários separados: cache de nível 2 JPA e cache de método de Primavera.

Quando você configura seu aplicativo, você normalmente configura o provedor de cache do segundo nível do seu provedor JPA (hibernar, no meu caso) e você também configura a primavera com o espaço de nome "cache". Tudo está bem e você continua com o projeto. Mas há uma advertência. Se você seguir a maneira mais direta, você recebe dois gerenciadores de cache separados que carregam o mesmo arquivo de configuração de cache. Isso não é ruim per-se, mas é algo para pensar - você realmente precisa de dois gerenciadores de cache e os problemas que podem surgir a partir disso?

Provavelmente você não. Então você tem que se livrar do gerente redundante. Para fazer isso, você precisa configurar seu gerenciador de cache de primavera como compartilhado:

1
2
3
4
<bean id="ehCacheManager"
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="shared" value="true" />
</bean>

Isso significa que a primavera não criará uma nova instância do gerenciador de cache, mas reutilizará aquele já criado pelo hibernado. Agora, há algo para pensar aqui - dependerá da ordem da criação do feijão - se o feixe de fábrica da JPA ou o feixe de fábrica do gerenciador de cache será o primeiro. Por sorte, isso não importa para o resultado final, porque SingletonEhCacheRegionFactory reutiliza uma instância do gerenciador de cache existente se encontrar uma.

Então, agora você criou o gerenciador de cache jvm-singleton. Mas, em seguida, há outro problema que você pode encontrar se você tiver vários aplicativos implantados e você estiver usando o JMX. O gerenciador de cache registrou-se como um feijão JMX. Mas quando você tem singletons, várias aplicações tentarão registrar o mesmo gerenciador de cache várias vezes, e isso irá falhar. O resultado será um par de exceções no log e a incapacidade de controlar o gerenciador de cache de vários módulos. Um efeito colateral do mesmo problema fica no caminho, se você usar algo como Terracotta (a identidade do administrador do cache é importante). Por sorte, você tem uma solução fácil para isso. Basta adicionar uma propriedade à definição do feijão acima indicada:

1
<property name="cacheManagerName" value="${module.name}" />

${module.name} e uma propriedade resolvida com um PropertyPlaceholderConfigurer e é configurável por webapp, então cada webapp pode ter um nome de módulo diferente. Dessa forma, o gerenciador de cache será acessível sob o nome especificado via JMX.

No geral, tenha cuidado com seus gerentes de cache. Mesmo no caso de você estar usando diferentes cache, jpa e provedor DI, você deve verificar os cenários descritos acima.