32 votes

Opérations NHibernate sur les lectures

J'ai lu la documentation et expliqué pourquoi il est fortement recommandé d'utiliser des transactions sur des opérations de lecture dans NH. Cependant, je n'ai pas encore totalement "acheté" dedans. Est-ce que quelqu'un peut essayer de l'expliquer sans me dire quoi que ce soit à RTFM, ce que j'ai déjà fait? ;)

24voto

Chris S Points 32376

Ce post à partir de l'un des auteurs peut-être votre réponse:

Même si nous sommes seulement à la lecture des données, nous souhaitez utiliser une transaction, car à l'aide d'une transaction de s'assurer que nous obtenons un résultat cohérent à partir de la base de données. NHibernate supposer que tous les accès à la base de données est effectuée en vertu d'un transaction, et à déconseiller fortement toute utilisation de la session sans des transactions.

En laissant de côté la question de la sécurité de travailler avec les transactions, les l'hypothèse que les opérations sont coûteux et nous avons besoin d'optimiser leur est un faux. Comme déjà mentionné, les bases de données sont toujours en cours d'exécution dans des transactions. Et bases de données ont été fortement optimisé pour fonctionner avec les des transactions. La question est de savoir ce que c'est par déclaration ou par lot. Il ya une certaine quantité de travail qui ont besoin d' à faire pour créer et disposer d'une de transaction, et d'avoir à le faire par la déclaration est effectivement plus coûteux que le faire par lot.

8voto

Mike Scott Points 6062

Ce que les autres ont dit, c'est vrai, mais ils n'ont pas souligné que le problème de ne pas contrôler les transactions de vous-même, c'est que si vous effectuez plusieurs NHibernate opérations sans une transaction explicite, chacune de ces opérations auront lieu dans les transactions distinctes.

Donc, vous pouvez facilement obtenir une incohérence entre les opérations. En faisant explicitement le départ d'une NHibernate transaction puis d'effectuer les opérations, vous avez la garantie de la cohérence dans l'ensemble de ces opérations.

C'est vrai, bien sûr, pour TOUTE couche d'accès aux données qui, implicitement, commence transactions pour vous si vous n'avez pas. Il n'est pas limité à NHibernate.

6voto

Paco Points 6156
 var fooIdFromDb = ExecuteQuery("Select Id from Foo where something = somethingelse");
var barsFromDb = ExecuteQuery("Select * from Bar where FooId = " + fooIdFromDB);
 

Que se passe-t-il si une autre transaction supprime les lignes de Bar entre les deux requêtes? Vous aurez des problèmes avec les données fantômes. Ce n'est pas un problème spécifique à NHibernate. Vous aurez le même problème avec tout autre type d'accès à la base de données sans utiliser de transactions. Vous devriez lire le manuel sur les transactions en général au lieu du manuel NHiberante.

5voto

Abel Points 24335

Concentrons-nous sur ce qui se passe si vous ne pas utiliser les transactions. Il est de coutume, mais pas obligatoire, que vous fermez la Session à la fin du traitement, mais avant de commencer la lecture des données (c'est à dire, la Vue). Cette méthode est propagé sous le terme "Open Session in View" (même s'il a évidemment un modèle pour la prévention de la lire avant de fermer). Ce modèle est souvent utilisé dans une application web où la session est ouverte lorsque la demande arrive et fermé juste avant l'écriture du flux de la réponse.

(N)Hibernate a besoin d'une séance et une opération. Quand vous lisez sans l'aide d'une transaction explicite, la transaction sera configuré pour vous. Quand vous lisez après une transaction est validée, le comportement dépend de NH configuration et le pilote.

Les deux ODBC et JDBC ne définissent pas ce qui se passe quand une connexion est fermée et il n'y a non validées ou unrollbacked de données. Lorsque la connexion est rouvert, il est possible qu'une nouvelle transaction est automatiquement démarré.

À l'aide de non-accès transactionnel ne peut être utilisé conjointement avec le paramètre auto-commit explicitement dans le NHibernate de configuration. Si non, la valeur par défaut du pilote est utilisé et il peut fonctionner, ou peut ne pas fonctionner.

En bref, il y a de nombreuses lacunes et des comportements indéfinis lorsque vous n'utilisez pas de transactions sur le lit. Il travaillera souvent, mais cela dépend de la configuration, les modèles, les pilotes. Il y a de grandes chances que vous ayez LazyInitializationExceptions, ce qui est un résultat commun de lire après s'engager sans l'ouverture d'une nouvelle transaction.

La "meilleure pratique" consiste à utiliser une opération de lecture/écriture et un autre pour la lecture seule. Ceci est décrit brièvement dans le lien précédent, section "puis-je utiliser deux opérations en une session", mais nécessite plus de votre mise en œuvre.

Ce n'est pas seulement "utiliser des transactions pour les lire", c'est aussi: "utilisation de la même transaction que vous utilisez pour l'écriture que pour la lecture". (et puis, c'est vrai, et l'application réelle dépendra de vos schémas actuels, combien de niveaux il y a, de la mise en cache et de la configuration).

Mise à jour: élargi un peu, supprimé certaines ambiguïtés

3voto

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X