Pregunta

Estoy buscando Hibernate para un sistema que necesita trabajar en una red poco confiable. Hay una única base de datos central a la que necesitamos acceso de lectura-escritura, pero está disponible a través de una red Wi-Fi bastante irregular. Además, puede haber pérdidas de potencia que no cierran la aplicación limpiamente, por lo que cualquier solución debe tener un caché persistente que pueda sobrevivir a los ciclos de potencia. Por último, este es un sistema integrado con solo memoria modesta y espacio en disco, por lo que, por ejemplo, hacer una replicación completa de la base de datos no es una estrategia factible.

Tengo una comprensión básica del almacenamiento en caché del segundo nivel hibernado, y me pregunto si es posible configurar esto con algo como ehcache para resolver este problema, pero el impulso principal de eso parece ser el rendimiento que no tiene disponibilidad, por lo que no soy consciente de Cuáles podrían ser las trampas.

También estoy bastante dispuesto a considerar otras estrategias que implican replicación en una base de datos local. Prefiero no tener que hacer demasiado de la pesada levantamiento para implementar esto.

Buscando algo de experiencia o posibles alternativas.

¿Fue útil?

Solución 6

El replicador de narciso (http://enterprise.replicator.daffodilsw.com/index.html) permite la replicación entre las fuentes JDBC. Soporte de actualizaciones bidireccionales, fusión y resolución de conflictos y réplicas parciales.

Esto se puede usar para sincronizar la base de datos principal con una réplica local (parcial). Puede usar Hibernate para hablar con la base de datos de réplica local y hacer todo lo demás fuera de ese proceso.

Otros consejos

"Además, puede haber pérdidas de potencia que no cierran la aplicación limpiamente, por lo que cualquier solución debe tener un caché persistente que pueda sobrevivir a los ciclos de potencia".

Ya tienes una solución en tu mente con caché de nivel 2 de hibernación. Pero no dijiste cuáles son los requisitos reales. Tienes una red poco realable. Está bien, tienes un suministro de energía poco revelable. Eso también está bien. Ahora, ¿qué nivel de servicio quieres lograr? ¿Qué es aceptable o no?

¿Es aceptable la pérdida de datos? ¿Cuánto podrías aceptar? ¿Qué riesgo acepta?

Para ser más explícito, digamos que tiene una réplica local de la base de datos o al menos parte de ella. Digamos que sabe cómo hacer cola/guardar la modificación realizada localmente. Digamos que almacena estas modificaciones en una drástica para estar seguros en caso de falla de energía. Digamos que puede fusionar los cambios con la base de datos principal cuando la conexión es disponible nuevamente.

Eso ya es muchas suposiciones. Ok, pero ¿qué sucede si un disco duro falla después de un PowerFailure? ¿Sabes que no le gusta la fallas de energía y tienden a dañarse en la falla de energía o incluso puede dañarse?

Así que se pone una redada y agrega una fuente de alimentación ininterrumpida. Qué lindo. Su evento de detección de falla de energía desde el sistema operativo. Termine su transacción actual y apague correctamente. Usted asciende a protegerlo de una falla en el disco.

Ok, pero ¿qué sucede si toda la computadora deja de funcionar? ¿Qué pasa en caso de fuego? ¿O daños por agua? Todo el disco se administrará, se no es recuperable de datos y lo que no se sincroniza con la base de datos central se pierde. ¿Es aceptable o no?

Incluso cuando el wifi está encendido, la fuente de alimentación funciona perfectamente ... ¿Cuál es la confiabilidad de la base de datos central de todos modos? ¿Tiene copias de seguridad regulares? O una solución de agrupación? ¿Estás seguro de que tu base de datos central es confiable de todos modos?

Desde el punto de vista de la base de datos, es fácil usar un clúster o copia de seguridad y usar transacciones para garantizar dataconsistencia. Todavía puede perder datos (si no usa un clúster en particular), pero debería poder recuperarse hasta la última copia de seguridad para un ejemplo.

Pero si desea trabajar fuera de línea (con una base de datos disponible), y no es el único que puede modificar la base de datos, se producirán conflictos. Esto ya no es un caché, hibernado o cualquier problema técnico.

Este es un problema funcional. ¿Qué hacer cuando ocurren varias modificaciones fuera de línea y tienes que fusionarte? ¿Qué es aceptable? Lo que no es. Esto podría ser que, en reconexión, se aplica el cambio más reciente, se descartan los cambios anteriores. O se detectan conflictos ptentiales y solicita al usuario que se ocupe de ellos. Puede intentar aplicar el cambio de cola y aplicarlos todos ...

Tendería a considerar que puede ofrecer un "modo fuera de línea", pero sus usuarios deben tener en cuenta que están fuera de línea y deben tener una notificación cuando el cambio se está haciendo permanente en la base de datos central con una resolución de conflictos eventual. Pero ese es mi punto de vista.

No puede esperar tener éxito con una red como esa entre Hibernate y la base de datos.

Le recomiendo que defina un conjunto de operaciones atómicas de alto nivel, y luego defina un conjunto de (por ejemplo) servicios de descanso para ellos. O, si lo desea, puede usar SOAP y analizar las opciones WS-* para mensajes confiables para encargarse de reintentos y todos los demás detalles desordenados.

O bien, podría investigar si algo como Cassandra en todo el enlace funcionaría mejor que SQL, o algo más grande en la replicación.

¿Qué hay de hacer cola las operaciones de DB en una cola de mensajes duradera/persistente, y dejar que algunos mensajes de middleware manejen el problema de la red?

Dependiendo de cómo lo haga, los problemas de consistencia (bueno, "anomalía" es la palabra correcta, supongo) puede surgir, pero si tiene una red poco confiable y aún desea un rendimiento decente, entonces conformarse con una consistencia relajada podría ser el camino a seguir.

Dudaré en usar ehcache, etc. No fueron diseñados para esto y, por lo tanto, es posible que tenga que "estirar" del marco. Las colas de mensajes, por otro lado, tienen soluciones diseñadas para tales escenarios.

Si fuera solo un caso de conexión esporádica entre las dos máquinas, recomendaría mantener un registro de transacciones que se pueda reproducir y cada entrada marcada como procesada. Sin embargo, la memoria limitada puede dificultarlo.

Sin embargo, tal vez pueda almacenar el registro de transacción comprimido.

Hibernate (y el caché de segundo nivel) son De Verdad no diseñado para esto. Supongo que probablemente sería mejor usar un Java RDBMS incrustado a pequeña escala (por ejemplo, H2 o HSQLDB) como su cola temporal local (en el modo más duradero disponible) y luego haga la sincronización con un hilo de fondo. Luego, puede proporcionar una interfaz de usuario de sincronización conectada a ese hilo de fondo para proporcionar cierto grado de comentarios para el usuario.

Por cierto, Hibernate es un poco gordo para volcar en un ambiente incrustado. Es posible que desee considerar mybatis en su lugar.

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