Je rencontre des problèmes avec mes isessions dans NHibernate. Je continue à obtenir "la session fermée!" les erreurs. Quelqu'un peut-il me montrer le modèle correct, y compris une définition des méthodes suivantes et pour utiliser chacun:
private Object _awardBadgesLock = new object(); //In case the callback happens again before the previous one completes public void AwardBadges() { lock (_awardBadgesLock) { using(session = _repository.OpenSession()) { foreach (var user in _repository.All<User>().ToList()) { var userPuzzles = _repository.All<Puzzle>().ByUser(user.Id).ToList(); var userVotes = _repository.All<Vote>().Where(x => x.UserId == user.Id).ToList(); var userSolutions = _repository.All<Solution>().ByUser(user.Id).ToList().Where(x => !userPuzzles.Select(y => y.Id).Contains(x.PuzzleId)); var ledPuzzles = GetPuzzlesLedByUser(user.Id); AwardPlayerBadge(user, userSolutions); AwardCriticBadge(user, userVotes); AwardCreatorBadge(user, userPuzzles); AwardRidlerBadge(user, userPuzzles); AwardSupporterBadge(user, userVotes); AwardPopularBadge(user, userPuzzles); AwardNotableBadge(user, userPuzzles); AwardFamousBadge(user, userPuzzles); AwardLeaderBadge(user, ledPuzzles); using (var tx = _repository.BeginTransaction()) { _repository.Update(user); tx.Commit(); } } } } }
4 Réponses :
Vous devez toujours utiliser Session.Dispose (); Les autres sont pour très em> des occurrences étranges p>
J'utilise l'instruction "Utilisation" qui appelle le dispositif. Je reçois toujours l'erreur et je n'arrive pas tout le temps. Juste une partie du temps.
Je vous conseille de lire la documentation de l'isession sur https://nhibernate.svn.sourceforge.net /svnroot/nhibernate/trunk/nhibernate/src/nibernate/isession.cs p>
Quoi qu'il en soit, la manière appropriée de nettoyer lorsque vous avez terminé la session consiste à le disposer (ou mieux, entourez l'utilisation avec l'utilisation de la déclaration). Dans ce cas, "Utilisation" ferme la session et supprime le finaliseur, c'est-à-dire empêchant l'objet de session de survivre inutilement à la collecte des ordures suivantes et sauve la mémoire. P>
Si la connexion est déjà fermée, l'élimination ne jettera pas une exception. D'autre part, la fermeture après l'élimination (ou après la fermeture) jette une exception. p>
La documentation recommande d'appeler la déconnexion au lieu de la fermeture, car cela libère la connexion au pool de connexion. Vous devez appeler la reconnexion avant d'utiliser une session déconnectée. p>
Pour mes besoins, j'utilise toujours "en utilisant" quels appels disposent et n'ont jamais utilisé les deux fonctions. P>
Mais il utilise "en utilisant" n'est-ce pas? ... en utilisant (session = _repository.opensession ()))
Le problème réside dans le fait que l'isession n'est pas la sécurité du thread. Il y avait de multiples méthodes étant cuites sur des threads distincts qui ont tous créé une instance d'isession. La question était vraiment avec le fait qu'ils ont tous partagé la même sessionFactory. Image de ces méthodes sont tirées sur des threads distincts:
ISessionFactory _sessionFactory; void MethodOne() { using(ISession session = _sessionFactory.OpenSession()) { //Do something with really quick with the session //Then dispose of it } } void MethodTwo() { //OpenSession() actually returns the same instance used in the //previous method that has already disposed of the object; using(ISession session = _sessionFactory.OpenSession()) { //Do something with a session that has already been disposed //throws errors } }
Intéressant - quel iSessionFactory code> Utilisez-vous? La documentation de l'interface dit "Mises de configuration doit être threadsafe. "
C'est exactement le problème. "Les implémentateurs doivent être threadsafe" car SéanceFactory n'est pas le fil-de-vin.
Droite, mais quel i> concret iSessionFactory code> implémentation?
SéanceFactoryImpl CODE>? Je suis sûr que si vous pouvez reproduire le problème (ou mieux encore, localiser le bug
MICAH, cela me confonde tout à fait: je pense vraiment que la sessionFactory est la sécurité du thread (selon NHibernate Docs: "Un objet IsessionFactory est un objet Threadsafe coûteux à créer pour être partagé par tous les threads d'application.") Je vais aller de l'avant. Dans mon projet avec l'hypothèse, cela est vrai et que vous avez utilisé une mise en œuvre de buggy ou que les bugs reposent ailleurs.
À propos du problème, votre méthode de verrouillage est correcte tant que vous disposez de la session, mais probablement le bogue réside dans une autre partie de vos codes. À propos de la conception, il est préférable que vous transmettez la variable de session à des référentiels en raison de la mise en œuvre de l'unité de travail de la transaction de la session et de la racine agrégée comme celle-ci:
using (ISession session = SessionFactory.OpenSession()) { Repository1 rep1 = new Repository1(session); Repository2 rep1 = new Repository2(session); Repository3 rep1 = new Repository3(session); // some logics using (var tx = session.BeginTransaction()) tx.Commit(); }
Oui, j'ai une application Web, mais je n'ai pas l'intégration de la session NHibernate avec session Web.
Est-ce que ce souhait est utilisé ailleurs? Parce que, un autre appel d'oppensession () perdrait le premier.