181 votes

NHibernate ISession Flush: Où et quand l'utiliser, et pourquoi?

L'une des choses qui me confus est l'utilisation de la session.Chasse d'eau,en liaison avec la session.S'engager, et de la session.De près.

Parfois session.Près des œuvres, par exemple, il engage toutes les modifications que j'ai besoin. Je sais que j'ai besoin d'utiliser commettre lorsque j'ai une opération ou d'une unité de travail avec plusieurs crée/mises à jour/suppressions, de sorte que je peux choisir de la restauration si une erreur se produit.

Mais parfois, j'ai vraiment entravé par la logique derrière session.Chasse d'eau. J'ai vu des exemples où vous avez une session.SaveOrUpdate (), suivie d'une chasse d'eau, mais quand j'enlève les Rincer, il fonctionne très bien de toute façon. Parfois je tombe sur des erreurs sur la Chasse déclaration disant que la session a expiré, et la suppression de ce fait, je n'ai pas rencontré cette erreur.

Quelqu'un aurait-il un bon guide pour savoir où ni quand utiliser une Chasse d'eau? J'ai vérifié le NHibernate de la documentation, mais je ne peut toujours pas trouver une réponse simple.

229voto

Matt Hinze Points 9686

Brièvement:

  1. Toujours utiliser des transactions
  2. Ne pas utiliser Close(), au lieu envelopper vos appels sur un ISession à l'intérieur d'un using déclaration ou de gérer le cycle de vie de votre ISession quelque part d'autre.

À partir de la documentation:

De temps à autre l' ISession exécutera les instructions SQL nécessaires pour synchroniser les ADO.NET état de votre connexion avec l'état des objets en mémoire. Ce processus, chasse d'eau, se produit par défaut sur les points suivants

  • à partir de certaines invocations d' Find() ou Enumerable()
  • d' NHibernate.ITransaction.Commit()
  • d' ISession.Flush()

Les instructions SQL sont émis dans l'ordre suivant

  1. toutes les entités insertions, dans le même ordre que les objets correspondants ont été enregistrés à l'aide de ISession.Save()
  2. toutes les mises à jour de l'entité
  3. collection de toutes les suppressions
  4. toute la collection de l'élément de suppressions, mises à jour et des insertions
  5. collection de toutes les insertions
  6. toutes les entités suppressions, dans le même ordre que les objets correspondants qui ont été supprimés à l'aide de ISession.Delete()

(Une exception est que les objets à l'aide de code génération de code sont insérés lorsqu'ils sont enregistrés.)

Sauf si vous explicitement Flush(), il n'y a absolument aucune garantie à propos de quand la Session exécute les ADO.NET appels, seul l'ordre dans lequel ils sont exécutés. Cependant, NHibernate ne garantit que l' ISession.Find(..) méthodes ne sera jamais de retour des données obsolètes; et ils ne seront pas de retour de données incorrect.

Il est possible de changer le comportement par défaut de sorte que la chasse se produit moins fréquemment. L' FlushMode classe définit trois modes différents: seuls les rincer au moment de la validation (et uniquement lorsque le NHibernate ITransaction API est utilisée), rincer automatiquement à l'aide de l'a expliqué routine, ou ne rincez jamais à moins d' Flush() est demandé explicitement. Le dernier mode est utile pour de longues unités de travail, où un ISession est maintenu ouvert et débranché pendant une longue période.

...

Aussi vous référer à cette section:

Fin de la séance consiste en quatre phases distinctes:

  • rincer la session
  • valider la transaction
  • fermer la session
  • gérer les exceptions

Rinçage de la Session

Si vous arrive d'être en utilisant l' ITransaction API, vous n'avez pas besoin de s'inquiéter à propos de cette étape. Il sera effectué de façon implicite lorsque la transaction est validée. Sinon, vous devez appeler ISession.Flush() pour s'assurer que toutes les modifications sont synchronisées avec la base de données.

Commettre la transaction de base de données

Si vous utilisez le NHibernate ITransaction API, cela ressemble à:

tx.Commit(); // flush the session and commit the transaction

Si vous êtes à la gestion de ADO.NET opérations vous-même, vous devez manuellement Commit() le ADO.NET des transactions.

sess.Flush();
currentTransaction.Commit();

Si vous décidez de ne pas valider vos modifications:

tx.Rollback();  // rollback the transaction

ou:

currentTransaction.Rollback();

Si vous rollback de la transaction, vous devez vous fermez immédiatement le et jetez la session en cours pour s'assurer que NHibernate interne de l'état est cohérent.

La fermeture de la ISession

Un appel à l' ISession.Close() marque la fin d'une session. La principale implication de Close() est que l'ADO.NET la connexion sera abandonnée par la session.

tx.Commit();
sess.Close();

sess.Flush();
currentTransaction.Commit();
sess.Close();

Si vous avez fourni votre propre connexion, Close() renvoie une référence à elle, de sorte que vous pouvez fermer manuellement ou de le retourner à la piscine. Sinon, Close() , il revient à la piscine.

13voto

Sean Carpenter Points 5588

Départ dans NHibernate 2.0, les transactions sont nécessaires pour DB opérations. Par conséquent, l' ITransaction.Commit() appel de gérer tout nécessaire de rinçage. Si pour une raison quelconque vous n'êtes pas à l'aide de NHibernate transactions, alors il n'y aura pas d'auto-rinçage de la session.

1voto

kapilgandhi Points 1

De temps à autre le ISession va exécuter les instructions SQL nécessaires pour synchroniser les ADO.NET état de votre connexion avec l'état des objets en mémoire.

Et toujours utiliser

en utilisant (var transaction = session.BeginTransaction()) {

                transaction.Commit();
            }

après les modifications sont validées que cela change pour enregistrer dans la base de données que nous utilisons transaction.Commit();

0voto

Paul T Davies Points 889

Voici deux exemples de mon code où il échouerait sans session.Flush():

http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html

à la fin de cela, vous pouvez voir une section de code où j'ai mis de l'identité insérer sur, enregistrer l'entité puis rincer, puis définir l'identité insérer off. Sans rincer, il semblait être le réglage de l'identité insérer sur et hors tension, puis de sauver de l'entité.

L'utilisation de la méthode Flush() m'a donné plus de contrôle sur ce qui se passait.

Voici un autre exemple:

L'envoi de NServiceBus message à l'intérieur TransactionScope

Je ne comprenez pas pourquoi, sur ce point, mais la méthode Flush() a empêché mon erreur se produise.

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: