Cómo mantener la Hibernación de caché coherencia de la ejecución de dos aplicaciones Java?

StackOverflow https://stackoverflow.com/questions/48733

  •  09-06-2019
  •  | 
  •  

Pregunta

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

Entonces tenemos una separada de la jvm que es el servidor el uso de este tipo de datos.Como se está ejecutando continuamente sólo tenemos una larga db sesión (sólo lectura).

Actualmente no hay intra-jvm caché involucrados -, por lo que manualmente la señal de una jvm de los otros.

Ahora, cuando la webapp cambia algunos datos, es la señal de que el servidor para volver a cargar los datos modificados.Lo que hemos encontrado es que tenemos que decirle a hibernate para purgar los datos y, a continuación, vuelva a cargarlo.Sólo hacer una búsqueda de combinación con la db no hacer el trabajo - principalmente en el respeto de los objetos de varias capas inferiores de la jerarquía.

Alguna idea de si hay algo fundamentalmente mal con este diseño o si alguien está haciendo esto y ha tenido mejor suerte de trabajar con hibernate en la recarga.

Gracias, Chris

¿Fue útil?

Solución

Una sesión de Hibernate carga todos los datos que lee de la base de datos en lo que ellos llaman el el primer nivel de cache.Una vez que una fila se carga de la base de datos, cualquier capturas posteriores para una fila con el mismo PK devolverá los datos de esta caché.Además, Hibernate gaurentees igualdad de referencia para objetos de la misma PK en una sola Sesión.

Por lo que entiendo, tu solo-lectura de la aplicación de servidor nunca cierra su sesión de Hibernate.Así que cuando la base de datos se actualiza por el de lectura-escritura de la aplicación, en la Sesión de sólo lectura servidor no es consciente del cambio.Efectivamente, su lectura de la aplicación sólo se carga en la memoria una copia de la base de datos y el uso de esa copia, que se vuelve obsoleto en su debido tiempo.

La forma más sencilla y mejor curso de acción que puedo sugerir es cerrar y abrir las Sesiones según sea necesario.Esto deja de lado el problema entero.Hibernate Sesiones se pretende ser una ventana para una corta duración de la interacción con la base de datos.Estoy de acuerdo en que hay un aumento en el rendimiento por no recargar el objeto de gráfico de nuevo y otra vez;pero hay que medir y convencerse de que vale la pena los dolores.

Otra opción es cerrar y volver a abrir la Sesión de forma periódica.Esto asegura que la lectura de la aplicación sólo funciona con datos, no más de un intervalo de tiempo dado.Pero definitivamente hay una ventana en la que se lea de la aplicación sólo funciona con datos obsoletos (aunque el diseño garantiza que se pone la fecha de datos a la larga).Esto podría ser permisible en muchas aplicaciones que usted necesita para evaluar su situación.

La tercera opción es el uso de un de caché de segundo nivel implementación y uso de corta duración de las Sesiones.Hay varias almacenamiento en caché de paquetes que trabajar con Hibernate con méritos y deméritos.

Otros consejos

Chris, estoy un poco confundido acerca de sus circunstancias.Si entiendo correctamente, usted tiene un web app (leer/escribir) una aplicación independiente (solo lectura?) usando 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.Es ese derecho?

Si es así, ha considerado el uso de un segundo nivel de caché de la aplicación?Me pregunto si usted podría ser capaz de utilizar un clúster de caché, que es compartida por la aplicación web y la aplicación independiente.Creo que SwarmCache, el cual está integrado con Hibernate, permitirá a este, pero no he probado a mí mismo.

En general, sin embargo, usted debe saber que el contenido de un determinado caché nunca será consciente de la actividad por otra aplicación (por eso sugiero que ambas aplicaciones comparten una memoria caché).Buena suerte!

Desde mi punto de vista, debe cambiar el subrayado de Hibernación de la caché para que uno, que apoya a modo agrupado.Podría ser un JBoss Cache o un Enjambre De Caché.La primera de ellas tiene un mejor soporte de sincronización de datos (replicación y la invalidación) y también es compatible con la JTA.

Entonces usted será capaz de configurar la sincronización de la caché entre la aplicación web y el servidor.Busque también en el nivel de aislamiento de si va a utilizar JBoss Cache.Yo creo que usted debe utilizar READ_COMMITTED de modo que si usted desea obtener nuevos datos en un servidor de la misma sesión.

Los más utilizados en la práctica es tener un Gestionada Por Contenedor Gerente De La Entidad de modo que dos o más solicitudes en el mismo recipiente (es decir, Glassfish, Tomcat, Websphere) pueden compartir el mismo cachés.Pero si no se utiliza un contenedor de Aplicación, ya que se usa el Juego!por ejemplo, luego me iba a construir algunas de webservices en la principal de la Aplicación para leer/escribir constantemente en la memoria caché.

Creo que el uso de datos obsoletos es una puerta abierta para el desastre.Como los Únicos convertido en Multitons, lea las aplicaciones que sólo son a menudo un escribir a veces.

Cinturón y llaves :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top