Je suis assez sûr Finaliser est toujours de mauvaises nouvelles sur JVMs plus tard - est-il une alternative?

StackOverflow https://stackoverflow.com/questions/5359367

  •  27-10-2019
  •  | 
  •  

Question

Je voudrais mettre en œuvre un système de type ORM qui peut sauver des mises à jour de POJO quand ils sont par l'appelant ne sont plus accessibles.

Je pensais que les classes de référence pourraient le faire, mais ils semblent n'enqueue la référence après que l'objet a été effacé (j'espérais qu'il était quand ils ont pu être collectées), donc une fois en file d'attente la méthode .get () retournera toujours null.

Je pourrais utiliser un finaliseur mais la dernière fois que j'ai vérifié les étaient discutables (non garanti de fonctionner rapidement ou courir du tout) - Je crois qu'une combinaison de finaliseurs et runShutdownHook () fonctionnerait, mais qui devient en territoire assez marécageux <. / p>

Y at-il un autre chemin que je ne pense pas d'ailleurs l'obligation « Juste l'appel de l'appelant .save () quand il a fait »?

Était-ce utile?

La solution

Vous essayez juste de ne pas avoir à appeler save() sur tous les POJO que vous modifiez?

Cela peut être fait en utilisant de manière fiable un objet de la session de la persistance, comme ceci:

  1. Ouvrir un nouvel objet de la session.
  2. Charger des objets via l'objet de la session. L'objet de la session maintient des références à tous les objets qu'il charge.
  3. Apportez toutes les modifications apportées aux objets chargés. Il ne faut pas appeler un méthode de sauvegarde sur les objets mis à jour.
  4. Fermez l'objet de la session. La session enregistre tous ses objets. Il pourrait même être assez de fantaisie pour conserver une copie des données chargées propres, comparer tous ses objets aux données propres et ne conserver que ceux qui ont été modifiés.

Et si vous ne voulez pas passer des objets de session dans votre code, vous pouvez prendre les choses un peu plus loin avec l'unité de travail modèle, associant un objet de session au thread courant:

  1. Lancer une unité de travail. Cela crée un objet de session dans les coulisses et l'associe avec le thread courant.
  2. Charger des objets. Chaque fois qu'un objet est chargé, votre ORM associe automatiquement avec un objet de session en fonction du thread courant.
  3. Apportez toutes les modifications apportées aux objets chargés. Il ne faut pas appeler un méthode de sauvegarde sur les objets mis à jour.
  4. Remplissez l'unité de travail. Cela ferme l'objet de la session, l'enregistrement de tous les objets.

Elle corrige plusieurs problèmes avec une solution à base de joignabilité:

  • Vous ne dépendez pas le ramassage des ordures, non déterministes qui peuvent avoir une longue période entre les courses, ou pas exécuté du tout.
  • Tous les objets modifiés en une seule opération sont enregistrées ensemble. Si vous comptez sur joignabilité, différents objets modifiés dans la même opération peut devenir inaccessible à des moments différents, ce qui signifie vos modifications peuvent être enregistrées dans la base de données en bits et-pièces.
  • Rollback est beaucoup plus facile - il suffit de donner à votre objet de session une méthode rollback (). Avec une solution de joignabilité, vous devez vous rappeler d'appeler rollback () sur tous les POJO modifiés si une opération échoue, ce qui est vraiment le même que votre problème d'origine.

voir peut-être http: // NHibernate. info / doc / patternsandpractices / NHibernate-et-les-unité de travail-pattern.html ou la recherche du modèle unité de travail et imiter certaines de ces idées.

Autres conseils

Utilisez le modèle d'observateur font construire une ClearanceManager et quelques éléments destructibles. IDestroyable est une interface qui est utilisée pour les observateurs qu'il contient la méthode void publique détruire () Le ClearanceManager est l'objet du ObserverPattern. Peut-être utiliser Singleton ici pour vous assurer d'avoir un seul objet ClearanceManager dans votre application.

Utilisez un ensemble internaly à l'intérieur du ClearanceManager (pas une liste pour assurer les objets peuvent simplement être ajoutée une fois)

soutenir une méthode addDestroyable (IDestroyable destoryable) (et peut-être une removeDestroyable).

Lors de l'exécution des classes pour lesquelles vous avez besoin d'émulation destructor, peut enregistrer les auto au ClearenceManager. addDestroyable (ce) ClearenceManager.getInstance ();.

Le ClearanceManager a une méthode doClearance (), qui doit simplement être appelé à la fin du procédé principal. Il itère jeté le Set privé et appelle détruire () sur chaque objet IDestroyable.

En procédant ainsi, vous pouvez imiter Destructeurs, sans les utiliser, parce que l'utilisation que vous perdez Destructeurs contrôle sur l'existance d'objet MyaBe nécessaire. Vous ne savez pas si vous écrasez Finaliser, lorsqu'elle est appelée.

Peut-être, si vous ne voulez pas appeler doClearance () dans votre méthode principale, vous pouvez utiliser ici, mais juste ici, un Finaliser réel destructor (). Parce qu'il ya des références dans le ClearenceManager aux objets nécessaires, ils ne seront pas détruites en premier. Mais peut-être mhh, s'il y a des références croisées .... mieux ne pas utiliser Finaliser, l'utilisation doClearance () et amusez-vous avec elle :)

Je pense que vous aboient ici le mauvais arbre.

Tous les mécanismes de finaliseur et de référence de Java basées sur joignabilité dépendent du collecteur des ordures afin de déterminer si les objets respectifs sont accessibles. Donc, si vous utilisez l'un des mécanismes de référence pour une sorte de mise au point, vous avez beaucoup les mêmes questions qui font finalize une mauvaise idée.

Il est techniquement possible de mettre en œuvre vos propres mécanismes pour faire joignabilité; par exemple. en mettant en place votre propre comptage de référence spécifique à l'application. Cependant, il est susceptible d'être coûteux, fragile, et rendre votre code horrible. (Comptage de référence en Java est susceptible d'être messier et plus fragile que dans C ++, parce que vous ne pouvez pas surcharger les opérateurs d'affectation de référence pour faire en sorte que les compteurs de référence sont ajustées de manière transparente. Ainsi, chaque besoins d'affectation de référence à envelopper dans un appel de méthode.) Donc, Je dirais que faire votre propre analyse de joignabilité est une mauvaise idée .

Alors, pour être pratique, vous devez soit:

  • repenser votre conception afin que vous ne faites pas les choses en fonction de joignabilité, ou
  • en direct avec les conséquences de l'utilisation Finaliser.

La première option est clairement le meilleur, l'OMI.

peut-être vous pouvez sous-classe PhantomReference, et stocker les données nécessaires pour les actions finales.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top