J'ai une application à l'aide de JPA, Hibernate et Ehcache, ainsi que le déclaratif du printemps transactions. La charge sur dB est plutôt élevée, donc tout est mis en cache pour accélérer les choses, y compris les collections. Maintenant, ce n'est pas un secret que les collections sont mises en cache séparément des entités qui les possèdent donc si je supprime une entité qui est un élément de telle Cached Collection, persistez une entité qui devrait être un élément d'un, ou mettre à jour un une entité de telle sorte qu'il voyage d'une collection à une autre, je dois effectuer l'expulsion à la main. p>
J'utilise donc un auditeur d'événements Hibernate qui maintient une trace des entités insérées, supprimées ou mis à jour et enregistre cette information pour une synchronisation des transactions enregistrée auprès du ressort gestionnaire de transaction pour agir. La synchronisation exécute alors l'expulsion une fois la la transaction est commise. P>
maintenant le problème est strong> que très souvent, une autre transaction concomitante parvient à trouver
une collection dans le cache qui vient d'être expulsé (ces événements sont généralement des dixièmes d'un
Deuxièmement, séparément selon le journal) et naturellement, provoque une impression d'entitéNotFoundException. p>
Comment puis-je synchroniser ce produit correctement? em> p>
J'ai essayé de faire l'expulsion dans chacune des 4 méthodes de transactionNchronisation (qui
sont invoqués à différents moments dans le temps relatif à la fin de la transaction), cela n'a pas aidé. P>
3 Réponses :
Essentiellement ce que vous devez faire est de forcer une lecture de la base de données dans le cas où une collection est au processus ou vient d'être expulsée. Une façon de faire cela serait de marquer la collection aussi sale dès que la demande d'expulsion a été reçue mais avant d'entrer dans la transaction pour la modifier. Toute transaction concomitante qui vient vérifiera le drapeau sale et s'il est défini sur TRUE, il devrait obtenir les données de la base de données sinon il peut être lu dans le cache. Vous devrez peut-être modifier vos paramètres de transaction DB afin que les transactions simultanées bloquent jusqu'à ce que l'une mise à jour des données se termine afin que les données correctes soient lues à partir de la DB. Une fois la transaction terminée, vous pouvez ensuite réinitialiser le drapeau sale sur false. P>
Vous pouvez également créer une serrure sur la collection mise en cache lors d'une mise à jour, d'insérer ou de supprimer est due pour tant que l'expulsion dure. Cela garantira qu'aucune autre transaction ne peut lire / modifier la collection mise en cache jusqu'à la fin du processus d'expulsion. P>
Il est expulsé en dehors d'une transaction, au fait. Et je dois chercher l'API pour les marquer sale, merci. En outre, comment puis-je faire synchroniser Hibernate sur ce verrou que vous avez suggéré d'ajouter?
Apparemment, le drapeau sale de persistancecollection ne fera pas, car différentes transactions obtiennent des instances différentes de la même collection. Quant aux serrures, je vais regarder dans cette prochaine et j'apprécierais vraiment que quelqu'un me dirige à l'API appropriée. Ehcache ne prend pas en charge le verrouillage autant que je sache, regarda cette première chose.
Pourquoi ne pouvez-vous pas garder les collections à jour? I.e. Lorsque vous ajoutez un objet, ajoutez l'objet à la collection auquel il appartient. Lorsque vous supprimez un objet, retirez-le de la collection. Dans mon expérience lors de l'utilisation d'un cache avec Hibernate ou JPA, l'état de l'objet (pas l'état de la base de données) est mis en cache afin de vous assurer que votre modèle d'objet En mémoire est synchronisé avec le modèle d'objet sur la base de données. P>
ou je manque quelque chose? Pourquoi ne pouvez-vous pas simplement garder les collections uptodate? P>
C'est une application multithreadée, qui transmettait la même instance à jour avec une collection à jour autour semble être une sorte de difficile car il existe toutes sortes d'opérations simultanées qui prennent de temps à compléter et que j'ai tendance à utiliser EntityManager.getByID beaucoup pour aller chercher le dernier état d'une entité.
Je pense que vous devez faire référence à ce lien: - Hibernate: Cape Clean Cache du 2e niveau en cascade Supprimer les articles < / a> Voir, hibernate ne supprime pas réellement l'objet du cache .. repos u peut obtenir la réponse de la liaison ci-dessus p>