Comment configurer Hibernate pour lire/écrire de différentes sources de données?
À l'aide de Spring et Hibernate, je veux écrire un maître MySQL base de données, et de les lire à partir d'une ou plusieurs répliqué esclaves dans le nuage à base de Java webapp.
Je ne peux pas trouver une solution qui est transparent pour l'application du code. Je n'ai pas vraiment envie de changer mon DAOs pour gérer les différents SessionFactories, comme cela semble très salissant et les couples le code avec un serveur spécifique de l'architecture.
Est-il possible de dire à Hibernate d'acheminer automatiquement CRÉER/mettre à JOUR des requêtes à une source de données et SÉLECTIONNEZ à l'autre? Je ne veux pas faire toute la fragmentation, ou quoi que ce soit selon le type d'objet - il suffit de placer différents types de requêtes de différentes sources de données.
Hmm, qui sonne comme l'option la plus efficace que j'ai vu jusqu'à présent. Pense que je pourrais lui donner un aller, si il n'y a pas plus "transparent" option. Merci!
Comment au sujet de l'utilisation de MySQL proxy pour fractionner les opérations de lecture et écriture? Quelqu'un a déjà essayé?
OriginalL'auteur Deejay | 2010-12-08
Vous devez vous connecter pour publier un commentaire.
Un exemple peut être trouvé ici: https://github.com/afedulov/routing-data-source.
Printemps offre une variation de la source de données, appelé
AbstractRoutingDatasource
. Il peut être utilisé à la place de la norme de la source de données de mise en œuvre et permet un mécanisme pour déterminer le béton de la source de données à utiliser pour chaque opération au moment de l'exécution. Tout ce que vous devez faire est de le prolonger et de fournir une mise en œuvre d'un résumédetermineCurrentLookupKey
méthode. C'est la place pour mettre en œuvre votre logique personnalisée pour déterminer le béton de la source de données. Objet renvoyé en sert comme d'une recherche de la clé. Il est généralement une Chaîne de caractères ou fr Enum, utilisé comme qualificatif au Printemps de configuration (détails à suivre).Vous demandez peut-être ce que c'est que DbContextHolder objet et comment faut-il savoir quelle source de données identificateur de retour? Gardez à l'esprit que
determineCurrentLookupKey
méthode sera appelée à chaque fois que TransactionsManager demande une connexion. Il est important de se rappeler que chaque transaction est "associé" à un thread séparé. Plus précisément, TransactionsManager lie de Connexion pour le thread courant. Par conséquent, afin de répartir les différentes opérations de cibles différentes Sources de données, nous devons nous assurer que chaque thread peut identifier de manière fiable dont la source de données est destinée à être utilisée. Cela fait qu'il est naturel d'utiliser ThreadLocal variables pour la liaison spécifique de la source de données à un Fil, et donc à une Transaction. C'est comment il est fait:Comme vous le voyez, vous pouvez également utiliser un enum comme la clé et le Printemps sera de prendre soin de la résoudre correctement en fonction du nom. Associés de la source de données de configuration et les clés pourrait ressembler à ceci:
À ce stade, vous pourriez trouver vous-même faire quelque chose comme ceci:
Maintenant, nous pouvons le contrôle de source de données qui sera utilisée et suivre les demandes comme il nous plaît. Semble bon!
...Ou est-il? Tout d'abord, ces méthodes statiques pour un magique DbContextHolder vraiment coller. On dirait qu'ils n'appartiennent pas à la logique d'entreprise. Et ils ne le font pas. En plus de ne pas communiquer dans le but, mais ils semblent fragiles et sujettes à l'erreur (comment oublier de nettoyer le dbType). Et si une exception est levée entre le setDbType et cleanDbType? Nous ne pouvons pas l'ignorer. Nous devons être absolument sûr que nous réinitialiser le dbType, sinon Thread retourné pour le pool de threads peut être "cassée" de l'état, lors de l'écriture d'une réplique dans le prochain appel. Nous avons donc besoin de ceci:
Aïe
>_<
! Absolument, cela ne ressemble pas à quelque chose que je voudrais mettre dans chaque lecture seule méthode. Pouvons-nous faire mieux? Bien sûr! Ce modèle de "faire quelque chose au début d'une méthode, puis faire quelque chose à la fin" devrait sonner une cloche. Aspects à la rescousse!Malheureusement, ce poste a déjà eu trop longue pour couvrir le sujet de la création d'aspects. Vous pouvez suivre les détails de l'utilisation des aspects à l'aide de cette lien.
Si vous n'avez pas l'esprit, merci de le supprimer de votre downvote.
Je ne suis pas le bas de l'électeur. Mais avoir un upvote 🙂
Dans le cas où si vous êtes à la recherche pour configurer RoutingDataSource via Java au lieu de XML. Aller à travers : baeldung.com/spring-abstract-routing-data-source
Comment serait-ce de travailler lorsque l'esclave prend le pas sur le rôle de maître? La mise en œuvre ont à garder le contrôle sur les sources de données pour déterminer celui qui a tenu le rôle de maître?
OriginalL'auteur Alex Fedulov
Je ne pense pas que la décision qui Choisit de se rendre dans une DB (un esclave) et de CRÉER ou de MISES à jour devraient aller à un autre (le maître) est une très bonne décision. Les raisons sont:
Je vous conseille l'aide du maître DB pour tous les ÉCRIRE flux, avec toutes les instructions dont ils pourraient avoir besoin (qu'il Choisit, mettre à JOUR ou INSERTS). Ensuite, l'application de traiter avec la lecture des flux peut lire à partir de l'esclave DB.
Je voudrais aussi conseiller à la séparation des DAOs, chacun avec ses propres méthodes, de sorte que vous aurez une distinction claire entre la lecture seule des flux et de l'écriture/mise à jour des flux.
2) je pensais que par exemple, une mise à JOUR de l'opération suppose une première SÉLECTIONNEZ ensuite une mise à JOUR sur l'opération qui a été récupéré à partir de la SÉLECTIONNER, de sorte que vous pourriez finir par faire le SELECT initial sur l'esclave et la mise à JOUR sur le maître, qui peut entraîner des difficultés de la définition des opérations et des problèmes lors de la réplication est toujours en cours (esclave ne contient pas toutes les données que le maître a).
1) la réplication MySQL est un processus indépendant d'outils ORM, donc je ne pense pas que peut aider à ici..
1) Si Hibernate est de faire de l'écrire, puis, quand une sélection est ensuite demandé si le cache est encore en vie alors il ne fait pas de frapper la base de données, il va utiliser la valeur qu'il a écrit qu'il est stocké dans le cache. L'utilisation de EHCache et en terre Cuite doit s'assurer que ce sera cohérent à travers les instances du serveur d'applications.
OriginalL'auteur octav
Vous pouvez créer 2 session usines et hava un BaseDao envelopper les 2 usines(ou les 2 hibernateTemplates si vous les utilisez) et d'utiliser les méthodes get avec sur l'usine et la saveOrUpdate méthodes avec les autres
OriginalL'auteur Liviu T.
Essayer de cette façon : https://github.com/kwon37xi/replication-datasource
Il fonctionne très bien et très facile à mettre en œuvre sans aucune autre annotation ou d'un code. Elle ne nécessite qu'
@Transactional(readOnly=true|false)
.J'ai été en utilisant cette solution avec la mise en veille prolongée(JPA),Spring JDBC Modèle, iBatis.
OriginalL'auteur KwonNam
Vous pouvez utiliser DDAL pour mettre en œuvre l'écriture du maître de la base de données et la lecture de base de données esclave dans un DefaultDDRDataSource sans modifier votre Daos, et en plus, DDAL à condition de chargement de la balance pour mulit-esclave bases de données. Il ne repose pas sur spring ou hibernate. Il y a un projet de démonstration pour montrer comment l'utiliser: https://github.com/hellojavaer/ddal-demos et la demo1 est juste ce que vous avez décrit la scène.
OriginalL'auteur allen