7
votes

Des transactions longues avec le printemps et l'hibernation?

Le problème sous-jacent que je veux résoudre est exécuté une tâche qui génère plusieurs tables temporaires dans MySQL, qui doivent rester suffisamment longtemps pour récupérer les résultats de Java après leur création. En raison de la taille des données impliquées, la tâche doit être complétée par lots. Chaque lot est un appel à une procédure stockée appelée JDBC. L'ensemble du processus peut prendre une demi-heure ou plus pour un ensemble de données volumineux.

Pour assurer l'accès aux tables temporaires, j'exécute toute la tâche, commençant à terminer, dans une seule transaction de ressort avec une transactionCallbackwithoutresultHithoutresultHithouResultHithouResultHithouTrésultHithoutresultHithouResultHoSultHoSultHoSult. Sinon, je pourrais obtenir une connexion différente qui n'a pas accès aux tables temporaires (cela se produirait de temps en temps avant que j'ai tout emballé dans une transaction).

Cela a fonctionné bien dans mon environnement de développement. Cependant, dans la production, j'ai eu l'exception suivante: xxx

Ceci s'est produit lorsqu'une tâche différente a tenté d'accéder à certaines des mêmes tables lors de l'exécution de ma transaction longue en cours d'exécution. Ce qui me confond est que la transaction à long terme n'entraîne ou met à jour que dans des tables temporaires. Tous les tables non temporaires sont uniquement sélectionnés uniquement. À partir de quelle documentation je peux trouver, le niveau d'isolation de transaction de ressort par défaut ne doit pas causer à MySQL de bloquer dans ce cas.

Donc, ma première question, est-ce la bonne approche? Puis-je m'assurer que je reçois à plusieurs reprises la même connexion via un modèle hibernate sans une transaction longue en cours d'exécution?

Si l'approche de transaction longue est la bonne, que dois-je vérifier en termes de niveaux d'isolation? Est-ce que ma compréhension est correcte que le niveau d'isolement par défaut dans les transactions Spring / MySQL ne doit pas verrouiller les tables qui ne sont accessibles que via Selects? Que puis-je faire pour déboguer quelles tables provoquent le conflit et empêchent les tables d'être verrouillées par la transaction?


0 commentaires

3 Réponses :


1
votes

Lorsque vous dites que votre table est temporaire, est-ce que la transaction est-elle scopée? Cela pourrait conduire à d'autres transactions (peut-être sur une transaction différente) ne pouvant pas la voir / y accéder. Peut-être une jointure impliquant une vraie table et une table temporaire verrouillent en quelque sorte la table vraie.

Cause root: Avez-vous essayé d'utiliser les outils MySQL pour déterminer ce qui verrouille la connexion? Cela pourrait être quelque chose comme le verrouillage de la ligne suivante. Je ne connais pas les outils MySQL qui bien, mais sur Oracle, vous pouvez voir quelles connexions bloquent d'autres connexions.

Délai de transaction: Vous devez créer une seconde source de piscine / source de données avec un délai beaucoup plus long. Utilisez ce pool de connexion pour votre longue tâche. Je pense que votre environnement de production est «essayant» de vous aider à détecter des connexions bloquées.


0 commentaires

7
votes

Je envisage de garder la transaction ouverte pendant une période prolongée du mal. Au cours de ma carrière, la définition de "étendue" est descendue de quelques secondes à Milli-secondes.

Il s'agit d'une source sans fin de problèmes non répétables et de problèmes de déchirure.

Je mordrais la balle dans ce cas et conserveriez un "journal de travail" dans le logiciel que vous pouvez rejouer en sens inverse pour nettoyer si le lot échoue.


3 commentaires

Avez-vous une solution au problème "Maintenir la connexion"? Dans mon cas, le printemps et l'hibernation médiatisent ma connexion à la base de données, et j'ai eu du mal à obtenir le même lien à chaque fois, sans recourir à tout envelopper dans une seule transaction. Sans maintenir la même connexion, je perds l'accès aux tables temporaires.


Si vous conservez un serveur de travail avec une pièce d'identité et les jalons atteints dans le traitement par lots, vous pouvez créer des tables régulières nommées comme temp_ _stuff. Basé sur le jalon arrivé, vous pouvez sauter de l'avance et continuer avec des processus de lots abandonnés. Une fois que le traitement est un (c'est-à-dire jalon d'atteinte), retirez les tables et le journal que vous avez atteint le jalon «nettoyé». Tous les traitements peuvent maintenant être effectués avec de belles transactions à grain. PeuCommence dans cette approche est que vous ne voyez pas un "instantané" de l'état de la DB lorsque le travail de lot a commencé. Cela peut être ou non être un problème.


C'est très bon conseil. J'ai cependant un problème restant. Une partie du traitement initial crée des tables temporaires accessibles dans chaque lot. Ce traitement initial prend beaucoup de temps, suffisant que ce serait une performance significative si elle devait être répétée pour chaque lot. Je ne sais pas comment gérer ce traitement initial, mais je vais lui donner plus de pensée.



0
votes

Comme mentionné Justin concernant le délai de transaction, j'ai récemment été confronté au problème dans lequel le pool de connexion (dans mon cas Tomcat DBCP à Tomcat 7), était censé marquer les connexions longues marquées Abandon, puis les fermer. Après avoir modifié ces paramètres, je pouvais éviter ce problème.


0 commentaires