Comment maintenir Hibernate cache la cohérence de l'exécution de deux applications Java?
Notre conception a une jvm qui est un jboss/webapp (lecture/écriture) qui est utilisé pour maintenir les données via hibernate (en utilisant jpa) de la db. Le modèle a 10-15 classes persistantes de 3 à 5 niveaux de profondeur dans les relations.
Nous avons ensuite séparé de la jvm qui est le serveur à l'aide de ces données. Comme il est en cours d'exécution en continu, nous avons juste un long db session (lecture seule).
Il n'existe actuellement aucun intra-jvm cache impliqués - nous avons donc manuellement le signal d'une jvm de l'autre.
Maintenant, quand la webapp modifications de certaines données, il signale le serveur pour recharger les données modifiées. Ce que nous avons constaté, c'est que nous avons besoin de dire hibernate pour purger les données, puis de les recharger. Juste faire un fetch/fusionner avec le db ne pas faire le travail - principalement en ce qui concerne les objets de plusieurs couches en bas de la hiérarchie.
Des idées sur la façon de savoir si il y a quelque chose de fondamentalement mauvais dans cette conception, ou si quelqu'un fait cela, et a eu plus de chance avec le travail avec mise en veille prolongée sur la recharge.
Grâce,
Chris
OriginalL'auteur Chris Kimpton | 2008-09-07
Vous devez vous connecter pour publier un commentaire.
Une session Hibernate charge toutes les données qu'il lit à partir de la DB dans ce qu'ils appellent le cache de premier niveau. Une fois qu'une ligne est chargée à partir de la DB, les extractions pour une ligne avec le même PK retournera les données à partir de ce cache. En outre, Hibernate gaurentees référence à l'égalité pour les objets avec le même PK en une seule Session.
De ce que je comprends, votre lecture seule application serveur ne ferme jamais sa session Hibernate. Ainsi, lorsque la DB est mise à jour par la lecture-écriture de l'application, la Session sur un serveur n'est pas au courant du changement. Effectivement, votre lecture seule application est en cours de chargement en mémoire une copie de la base de données et l'utilisation de la copie, ce qui devient obsolète.
Le plus simple et le plus sûr de l'action que je peux suggérer, c'est de fermer et d'ouvrir des Sessions en tant que de besoin. Cette élude le problème. Les Sessions Hibernate sont prévu pour être une fenêtre pour une courte durée interaction avec la DB. Je suis d'accord qu'il y a un gain de performance par pas de rechargement de l'objet graphique, encore et encore; mais vous avez besoin de mesurer et de vous convaincre qu'il vaut la peine les douleurs.
Une autre option est de fermer et rouvrir la Session périodiquement. Cela garantit que la lecture seule application fonctionne avec des données datant de moins d'un intervalle de temps donné. Mais il y a définitivement une fenêtre où la lecture seule application fonctionne avec des données périmées (bien que la conception garantit qu'il obtienne le à jour des données par la suite). Ce peut être autorisée dans de nombreuses applications, vous devez évaluer votre situation.
La troisième option consiste à utiliser un cache de second niveau la mise en œuvre et l'utilisation de courte durée des Séances. Il existe différents de la mise en cache des paquets qui travaillent avec Hibernate avec les mérites et les démérites.
OriginalL'auteur Binil Thomas
Chris, je suis un peu confus au sujet de votre situation. Si je comprends bien, vous avez à la fois une web app (lire/écrire) une application autonome (lecture seule?) l'utilisation d'Hibernate pour accéder à une base de données partagée. Les modifications que vous apportez avec l'application web ne sont pas visibles à l'application autonome. Est ce que le droit?
Si oui, avez-vous envisagé d'utiliser un autre cache de second niveau de la mise en œuvre? Je me demandais si vous pourriez être en mesure d'utiliser un cluster de cache qui est partagée par l'application web et l'application autonome. Je crois que SwarmCache, qui est intégré avec mise en veille prolongée, le permettra, mais je n'ai pas essayé moi-même.
En général, cependant, vous devez savoir que le contenu d'un cache ne sera jamais au courant de l'activité par une autre application (c'est pourquoi je suggère d'avoir deux applications partagent un cache). Bonne chance!
OriginalL'auteur erickson
De mon point de vue, vous devriez changer votre soulignent Hibernate cache, qui supporte le mode cluster. Il pourrait être un JBoss Cache ou un Essaim De Cache. Le premier a une meilleure prise en charge de la synchronisation des données (réplication et d'invalidation) et prend également en charge JTA.
Alors vous serez en mesure de configurer le cache de synchronisation entre l'application web et le serveur. Regarde aussi au niveau d'isolation si vous allez utiliser JBoss Cache. Je crois que vous devriez utiliser READ_COMMITTED mode si vous souhaitez obtenir de nouvelles données sur un serveur à partir de la même session.
OriginalL'auteur Andrey Vityuk
Le plus utilisé en pratique est d'avoir un Container-Managed Gestionnaire D'Entité de sorte que les deux applications ou plus dans le même conteneur (c'est à dire Glassfish, Tomcat, Websphere) peuvent partager le même caches.
Mais si vous n'utilisez pas une Application conteneur, parce que vous utilisez Jouer! par exemple, alors je voudrais construire des webservices dans le Application principale à lire/écrire régulièrement dans le cache.
Je pense que l'utilisation des données périmées est une porte ouverte à la catastrophe. Tout comme les Singletons devenir Multitons, en lecture seule les applications sont souvent un écrire parfois.
Ceinture et bretelles 🙂
OriginalL'auteur Nicolas Zozol