22 Stimmen

NHibernate Flush - Wie funktioniert es?

Ich bin etwas verwirrt darüber, wie Flush ( und NHibernate.ISession ) in NHibernate funktioniert.

Aus meinem Code geht hervor, dass ich beim Speichern eines Objekts mithilfe von ISession.Save(entity) kann das Objekt direkt in der Datenbank gespeichert werden.

Wenn ich jedoch ein Objekt aktualisiere, indem ich ISession.SaveOrUpdate(entity) o ISession.Update(entity) wird das Objekt in der Datenbank nicht aktualisiert - ich muss die ISession.Flush um sie zu aktualisieren.

Die Vorgehensweise zur Aktualisierung des Objekts ist wie folgt:

  1. Beziehen Sie das Objekt aus der Datenbank, indem Sie ISession.Get(typeof(T), id)
  2. Ändern Sie z. B. die Objekteigenschaft, myCar.Color="Green"
  3. Übertragen Sie die Daten zurück in die Datenbank, indem Sie ISession.Update(myCar)

Le site myCar wird nicht in der Datenbank aktualisiert. Wenn ich jedoch ISession.Flush dann wird sie aktualisiert.

Wann zu verwenden Flush und wann sollte man sie nicht verwenden?

0 Stimmen

30voto

Stefan Steinegger Punkte 62197

In vielen Fällen müssen Sie sich nicht darum kümmern, wann NHibernate geleert wird.

Sie müssen flush nur aufrufen, wenn Sie eine eigene Verbindung erstellt haben weil NHibernate nicht weiß, wann Sie eine Übergabe durchführen.

Was für Sie wirklich wichtig ist, ist die Transaktion. Während der Transaktion sind Sie von anderen Transaktionen isoliert, d.h. Sie sehen immer Ihre eigenen Änderungen, wenn Sie aus der Datenbank lesen, und Sie sehen die Änderungen anderer nicht (es sei denn, sie werden übertragen). Sie müssen sich also nicht darum kümmern, wenn NHibernate Daten in der Datenbank aktualisiert, es sei denn, sie werden übertragen. Sie sind ohnehin für niemanden sichtbar.

NHibernate flusht, wenn

  • Sie rufen commit
  • vor Abfragen, um sicherzustellen, dass Sie nach dem tatsächlichen Zustand im Speicher filtern
  • wenn Sie flush aufrufen

Beispiel:

using (session = factory.CreateSession())
using (session.BeginTransaction())
{
  var entity = session.Get<Entity>(2);
  entity.Name = "new name";

  // there is no update. NHibernate flushes the changes.

  session.Transaction.Commit();
  session.Close();
}

Die Entität wird bei der Übergabe aktualisiert. NHibernate erkennt, dass Ihre Sitzung verschmutzt ist und überträgt die Änderungen in die Datenbank. Sie müssen nur dann aktualisieren und speichern, wenn Sie die Änderungen außerhalb der Sitzung vorgenommen haben. (Das heißt, mit einer abgetrennten Entität, d.h. einer Entität, die der Sitzung nicht bekannt ist).


Hinweise zur Leistung: Flush führt nicht nur die erforderlichen SQL-Anweisungen zur Aktualisierung der Datenbank aus. Es sucht auch nach Änderungen im Speicher. Da es bei POCOs kein Dirty-Flag gibt, muss es jede Eigenschaft jedes Objekts in der Sitzung mit dem Cache der ersten Ebene vergleichen. Dies kann zu einem Leistungsproblem werden, wenn es zu oft durchgeführt wird. Es gibt einige Möglichkeiten, um Leistungsprobleme zu vermeiden:

  • Nicht in Schleifen spülen
  • Vermeiden Sie serialisierte Objekte (Serialisierung ist erforderlich, um auf Änderungen zu prüfen)
  • Utilice schreibgeschützte Einheiten wenn angebracht
  • Satz veränderbar = false wenn angebracht
  • Wenn Sie benutzerdefinierte Typen in Eigenschaften verwenden, implementieren Sie effiziente Equals-Methoden
  • Deaktivieren Sie die automatische Spülung vorsichtig, wenn Sie sicher sind, dass Sie wissen, was Sie tun.

0 Stimmen

Danke, aber wenn ich ein Objekt in der Datenbank aktualisiere, bedeutet das, dass ich meine eigene Transaktion erstelle? Oder warum muss ich sonst flush aufrufen, um die Datenbank zu aktualisieren?

1 Stimmen

Hatte es zu beheben: Sie müssen zu spülen, wenn Sie Ihre eigene Verbindung erstellt. NHibernate erstellt eine Verbindung für Sie, wenn Sie CreateSession aufrufen, aber Sie können Ihre eigene ADO.NET-Verbindung bereitstellen. normalerweise brauchen Sie das nicht. Wenn Sie dies nicht tun, müssen Sie auch keinen Flush aufrufen.

6voto

Frederik Gheysels Punkte 54908

NHibernate führt nur dann SQL-Anweisungen aus, wenn dies erforderlich ist. Es verschiebt die Ausführung von SQL-Anweisungen so lange wie möglich.

Wenn Sie zum Beispiel eine Entität mit einer zugewiesenen ID speichern, wird die Ausführung der INSERT-Anweisung wahrscheinlich verschoben. Wenn Sie jedoch eine Entität einfügen, die z.B. eine automatisch inkrementierte ID hat, muss NHibernate die Entität direkt INSERT, da es die ID kennen muss, die dieser Entität zugewiesen wird.

Wenn Sie flush explizit aufrufen, führt NHibernate die SQL-Anweisungen aus, die für die in dieser Sitzung geänderten/erstellten/gelöschten Objekte erforderlich sind.

Spülen

0 Stimmen

Der angegebene Link funktioniert nicht. Es heißt: "Dieser Inhalt ist auf Knol nicht mehr verfügbar".

1 Stimmen

@N30: Ich habe gerade den Link korrigiert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X