second example cache java hibernate caching

example - ¿Cómo mantener la coherencia de la memoria caché de Hibernate con dos aplicaciones Java?



hibernate-ehcache maven (4)

Chris, estoy un poco confundido acerca de tus circunstancias. Si entiendo correctamente, tiene una aplicación web (de lectura / escritura) independiente (solo lectura) que utiliza Hibernate para acceder a una base de datos compartida. Los cambios que realice con la aplicación web no son visibles para la aplicación independiente. ¿Está bien?

De ser así, ¿ha considerado utilizar una implementación de caché de segundo nivel diferente? Me pregunto si es posible que pueda usar un caché en clúster que sea compartido tanto por la aplicación web como por la aplicación independiente. Creo que SwarmCache, que está integrado con Hibernate, lo permitirá, pero yo no lo he probado.

Sin embargo, en general, debe saber que el contenido de un caché determinado nunca será consciente de la actividad de otra aplicación (es por eso que sugiero que ambas aplicaciones compartan un caché). ¡Buena suerte!

Nuestro diseño tiene un jvm que es un jboss / webapp (lectura / escritura) que se utiliza para mantener los datos a través de la hibernación (usando jpa) al db. El modelo tiene 10-15 clases persistentes con 3-5 niveles de profundidad en las relaciones.

Entonces tenemos un jvm separado que es el servidor que usa esta información. Como está funcionando continuamente, solo tenemos una larga sesión de DB (solo lectura).

Actualmente no hay un caché intra-jvm involucrado, por lo que señalamos manualmente un jvm del otro.

Ahora cuando la aplicación web cambia algunos datos, le indica al servidor que vuelva a cargar los datos modificados. Lo que hemos encontrado es que necesitamos decirle a hibernate que purgue los datos y luego los vuelva a cargar. Simplemente haciendo un fetch / merge con el DB no hace el trabajo, principalmente con respecto a los objetos de varias capas en la jerarquía.

Cualquier idea sobre si hay algo fundamentalmente malo en este diseño o si alguien está haciendo esto y ha tenido más suerte al trabajar con hibernación en las recargas.

Gracias, Chris


Una sesión de Hibernate carga todos los datos que lee de la base de datos en lo que llaman la memoria caché de primer nivel . Una vez que se carga una fila desde el DB, cualquier recuperación posterior para una fila con el mismo PK devolverá los datos de este caché. Además, los gaurentees de Hibernate hacen referencia a la igualdad para los objetos con el mismo PK en una sola sesión.

Por lo que entiendo, su aplicación de servidor de solo lectura nunca cierra su sesión de Hibernate. Por lo tanto, cuando la base de datos se actualiza mediante la aplicación de lectura y escritura, la sesión en el servidor de solo lectura no tiene conocimiento del cambio. De hecho, su aplicación de solo lectura está cargando una copia en la memoria de la base de datos y utilizando esa copia, que se vuelve obsoleta a su debido tiempo.

El curso de acción más simple y mejor que puedo sugerir es cerrar y abrir sesiones según sea necesario. Esto elude todo el problema. Las sesiones de Hibernate están destinadas a ser una ventana para una interacción efímera con el DB. Estoy de acuerdo en que hay una ganancia de rendimiento al no volver a cargar el objeto-gráfico una y otra vez; pero debes medirlo y convencerte de que vale la pena.

Otra opción es cerrar y volver a abrir la sesión periódicamente. Esto asegura que la aplicación de solo lectura funciona con datos no anteriores a un intervalo de tiempo determinado. Pero definitivamente hay una ventana donde la aplicación de solo lectura funciona con datos obsoletos (aunque el diseño garantiza que obtenga los datos actualizados con el tiempo). Esto podría ser permisible en muchas aplicaciones; necesita evaluar su situación.

La tercera opción es usar una implementación de caché de segundo nivel y usar sesiones de corta duración. Hay varios paquetes de almacenamiento en caché que funcionan con Hibernate con méritos y deméritos relativos.


Desde mi punto de vista, debe cambiar su caché Hibernate subrayado a esa, que admite el modo agrupado. Podría ser un JBoss Cache o un Swarm Cache . El primero tiene una mejor compatibilidad con la sincronización de datos (replicación e invalidación) y también es compatible con JTA.

Entonces podrá configurar la sincronización de caché entre la aplicación web y el servidor. También mire el nivel de aislamiento si usará JBoss Cache. Creo que debería usar el modo READ_COMMITTED si desea obtener nuevos datos en un servidor de la misma sesión.


La práctica más utilizada es tener un administrador de la entidad administrado por contenedor para que dos o más aplicaciones en el mismo contenedor (es decir, Glassfish, Tomcat, Websphere) puedan compartir los mismos cachés. Pero si no usa un contenedor de aplicaciones, ¡porque usa Play! por ejemplo, luego construiría algunos servicios web en la aplicación principal para leer / escribir de forma coherente en la caché.

Creo que usar datos obsoletos es una puerta abierta para el desastre. Al igual que los Singleton se convierten en Multitones, las aplicaciones de solo lectura a menudo son a veces de escritura .

Cinturón y tirantes :)