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.