2013-05-03 14 views
5

Ich muss mehrere NHibernate-Sitzungen in einer Transaktion registrieren. Derzeit mache ich folgendes:Mehrere NHibernate-Sitzungen in einer Transaktion

1) Erstellen Sie eine SQL-Verbindung, dbConn;

2) Anruf ISession session = ISessionFactory.OpenSession (dbConn) zum Erstellen einer ersten Sitzung;

3) Rufen Sie session.BeginTransaction() auf, um eine Transaktion zu beginnen.

4) Später im Code, erstelle ich eine neue Sitzung mit dem gleichen Anschluss:

ISession session2 = ISessionFactory.OpenSession (dbconn)

Wenn ich gegen jede Abfrage auszuführen versuchen, session2, erhalte ich folgende Fehlermeldung:

ExecuteReader benötigt den Befehl, um eine Transaktion zu haben, wenn die dem Befehl zugewiesene Verbindung in einem ausstehenden lokalen t ist Transaktion. Die Transaction-Eigenschaft des Befehls wurde nicht initialisiert.

NHibernate scheint nicht das zweite ISession (oder, genauer gesagt, das Command-Objekt, dass es für diese Sitzung erstellt) zu gewinnen, in der offenen Transaktion, auch wenn sie die gleiche Verbindung tut wiederzuverwenden.

Gibt es eine Möglichkeit, mehrere Sitzungen innerhalb derselben Transaktion zu haben?

Ich kann keine einzelne Sitzung verwenden, da ich eine lang andauernde Aufgabe habe, die über 1 Million Objekte lädt und erstellt. Wenn ich eine ISession verwende, verschlechtert sich die Leistung von 3000 Datenbankanforderungen pro Sekunde auf 20, aufgrund der Leistungsverschlechterung von NHibernate Flushes. Um dies zu lösen, möchte ich kurzlebige Sitzungen erstellen und sie schnell ablegen.

Der gesamte Prozess ist jedoch in eine Transaktion verpackt. Wenn ich unabhängige nachfolgende Sitzungen mit ihren eigenen Verbindungen erstelle, stoßen sie gegen die Tabellensperren, die von der ersten Transaktion gehalten werden, und frieren ein. Um dies zu lösen, müssen diese Sitzungen innerhalb derselben Transaktion ausgeführt werden.

Antwort

7

Dinge, die Sie

  • session.GetSession() zu erstellen Kind-Sitzungen mit dem gleichen Kontext tun können (Anschluss, Transaktion, mode)
  • wenn Sie Cascading nicht StatelessSession verwenden, die für diesen
  • gemeint ist Verwenden Sie session.Clear(); nach jeweils 50 Objekten
+0

* ISession scheint CreateSession nicht zu haben, zumindest ab 3.3.1. Ist diese Methode anderswo oder ist es in der neueren NHibernate-Version? * Ich habe ISession.Clear() bereits entdeckt und es hat super funktioniert. Es ist ein guter Vorschlag. – Alex

+1

Tut mir leid, es sollte "ISession.GetSession (EntityMode.Poco)" sein. behoben – Firo

Verwandte Themen