Ich würde dies umgestalten, um externe Transaktionssteuerung zu ermöglichen. Das Repository kann nicht den Umfang der Arbeitseinheit kennen, zu der verschiedene Lese-/Schreibaufrufe gehören, es sei denn, der Code, der die Aufrufe ausführt, teilt dies mit. Erwägen Sie, ein "Arbeitseinheits" -Muster einzurichten: Lassen Sie, ohne spezifische Details der Datenspeicherimplementierung preiszugeben, Objekten, die vom Repository abhängen, angeben, dass sie eine "Arbeitseinheit" beginnen, abbrechen oder abschließen.
public interface IRepository
{
public UnitOfWork BeginUnitOfWork()
public void CommitUOW(UnitOfWork unit)
public void AbortUOW(UnitOfWork unit)
public IQueryable<T> GetAll<T>(UnitOfWork unit)
public List<T> GetAll<T>()
public void Store<T>(T theObject, UnitOfWork unit)
public void Store<T>(T theObject)
}
Ihr Repository würde wahrscheinlich diese implementieren, indem ein eigenes Wörterbuch von SQL-Transaktionen beibehalten wird, die jeweils ein UnitOfWork Objekt verkeilt (dies so einfach wie eine leere instantiable Klasse sein kann, oder kann es Rahmen unabhängiger Informationen über Zustand liefern oder Metriken). Wenn Sie eine DB-Operation ausführen, werden Ihre Anrufer zuerst eine UOW anfordern und ihnen wird ein Token gegeben, mit dem sie den Kontext identifizieren, in dem sie einen DB-Aufruf tätigen. Das Objekt, das das Token abruft, kann es an andere Klassen übergeben, die DB-Operationen im selben Betriebskontext ausführen müssen. Die Arbeitseinheit bleibt geöffnet, bis die abhängige Klasse dem Repository mitteilt, dass sie beendet ist, was Lazy-Loads und atomare Multi-Operation-Prozeduren ermöglicht.
Beachten Sie, dass Überladungen keine Arbeitseinheiten erfordern. Es ist möglich und vielleicht notwendig, einfache Anrufe zu tätigen, ohne explizit eine Arbeitseinheit zu starten. In diesen Fällen kann Ihr Repository eine interne UOW erstellen, die angeforderte Operation ausführen und die Ergebnisse zurückgeben. Ein Lazy-Loading wird in diesen Fällen jedoch schwierig oder unmöglich sein; Sie müssen die gesamte Ergebnismenge in einer Liste abrufen, bevor Sie die interne UOW beenden.
Warum sollten Sie eine Transaktion um einen Lesevorgang wünschen? –
Ah, aus dem Artikel: "Auch wenn wir nur Daten lesen, sollten wir eine Transaktion verwenden, weil die Verwendung von Transaktionen gewährleistet, dass wir konsistente Ergebnisse aus der Datenbank erhalten. NHibernate geht davon aus, dass der gesamte Zugriff auf die Datenbank unter einer Transaktion erfolgt rät dringend von einer Nutzung der Sitzung ohne eine Transaktion ab. " Allerdings verstehe ich immer noch nicht, warum der Autor diese Deklamation macht. –