2012-04-10 6 views
0

Ich habe eine Situation, in der ich Daten von einer Abfrage abrufen muss, die fast eine halbe Minute ausführt und es auf eine Webseite bringt. (Es gibt keine Möglichkeit, diese Zeit zu reduzieren, da die maximale Menge an Optimierung darauf ausgeführt wurde) Ich verwende eine vierschichtige Architektur zusammen mit Entity Framework (EF, Datenzugriffsschicht, Biz Logic Layer, UI) für meine Anwendung. Ich versuche, die Singleton-Methode zu verwenden, wenn eine Instanz an die DAL erstellt wird (die DAL wiederum Daten aus der Datenbank abruft), so dass ich in der Lage sein werde, diese Instanz erneut zu verwenden, und zusätzliche Instanzen nicht erstellt werden in derselben Sitzung. Wie kann ich den Sitzungsstatus festlegen und die Verfügbarkeit der Instanz im Statusserver prüfen?Sitzungsstatusvariablen und Singleton-Klasse

public static Singleton getInstance() { 
    if (**instance == null**) 
     instance = new Singleton(); 
    return instance; 
    } 

Was sollte innerhalb des if Blocks liegen? Welchen Zustand sollte ich im Block if überprüfen? Ich bin mir nicht sicher, was ich tun soll.

PS: Diese Sitzung muss eine Zeitüberschreitung von 5 Minuten haben. Ich höre das kann in der Web.config Datei angegeben werden. ist es wahr?

+0

Sitzung ist eine Name Wert Sammlung. Rufen Sie die Instanz Ihres DALs mit dem Namen ab und überprüfen Sie, ob der Wert null ist. Wenn es nicht null ist, dann wirf es in eine Instanz deiner DAL. Für das, was es wert ist, würde ich diesem Muster nicht folgen. Was ist so teuer an der Erstellung Ihrer DAL, dass Sie nicht für jede Anfrage eine Instanz erstellen und entsorgen möchten? – Maess

+0

Jedes Mal, wenn ein Objekt der DAL erstellt wird, greift es auf die DB und somit auf die gespeicherte Prozedur zu, die die komplexe Abfrage enthält, und es dauert eine weitere Minute, bis die Daten ausgegeben werden. Ich denke daran, die Instanz zu speichern und sie zum zweiten Mal für einen schnelleren Zugriff zu verwenden. – krishgopinath

+3

Erstellen Sie für jede Benutzersitzung eine separate DAL? Warum sollte die DAL überhaupt sitzungsspezifisch sein? Kannst du nicht einfach eine Fabrik für die DAL mit einer statischen Eigenschaft darauf haben? Wenn die Eigenschaft aufgerufen wird, prüfen Sie, ob das statische Element der Factory der DAL-Instanz "null" ist.Wenn ja, instanziieren und zurückgeben. Wenn nicht, einfach zurück. – David

Antwort

1

Um ehrlich zu sein, sollten Sie lieber Entity Framework-Kontext verwenden und jedes Mal erstellen, wenn Sie Zugriff auf die Datenbank benötigen, d. H. In jeder Methode. Es ist optimiert, um auf diese Weise verwendet zu werden. Beim Verbindungs-Pooling wird sichergestellt, dass beim erneuten Erstellen des EF-Kontexts keine Strafe entsteht. Dies ist die beste Vorgehensweise.

Aber Ihre DAL könnte mehr sein als nur einfacher DB-Zugriff. Wenn Sie es für jede Sitzung als Singleton haben möchten, müssen Sie die Instanz bei der ersten Anforderung erstellen, sie in der Sitzung speichern und prüfen, ob sie vor der Verwendung vorhanden ist. Mit Thread-Sicherheit könnte der Code wie folgt aussehen:

class DALClass 
{ 
    private static object instanceLock = new object(); 

    public static DALClass Instance 
    { 
     get 
     { 
      if (Session["DALInstance"] == null) 
      { 
       lock (instanceLock) 
       { 
        if (Session["DALInstance"] == null) 
        { 
         Session["DALInstance"] = new DALClass(); 
        } 
       } 
      } 

      return (DALClass)Session["DALInstance"]; 
     } 
    } 
} 
+0

Ich denke nicht, dass das DAL-Objekt ein Singleton sein oder in der Sitzung zwischengespeichert werden sollte. Cache die Ergebnisse ja, aber nicht das Objekt, das die Arbeit erledigt. Höchstens die DAL sollte von der DI behandelt werden und auf einer einmal pro Web-Anfrage erstellt werden, siehe die Burg Dokumente: http://stw.castleproject.org/Default.aspx?Page=LifeStyles&NS=Windsor&AspxAutoDetectCookieSupport=1 –

+0

Wie ich in meinem zeigte Antwort, DAL in der Sitzung zu haben ist nicht die beste Idee. Wenn es nicht mehr gibt, wissen wir es nicht. –

+0

@Maciej: Ich habe den Kontext den Entitäten in der Sitzung zugewiesen. Ist das gut? – krishgopinath

1

Es klingt für mich wie Sie eine gut definierte Architektur haben, die Abhängigkeit Injection passen würde. Mit DI können Sie Ihren IOC-Container einfach dazu bringen, ein Singleton-Objekt oder ein transientes Objekt zurückzugeben. Seien Sie jedoch sehr vorsichtig bei der Verwendung von Singletons in einer Webumgebung, da sie oft mehr Probleme verursachen, als sie wert sind.

Wenn die Abfrage, die Sie ausführen, benutzerspezifische Daten enthält, würde ich wahrscheinlich die Ergebnisse dieser Abfrage in Sitzung innerhalb des Codes platzieren, der den UI-Teil Ihrer Anwendung erstellt, wenn Sie ein Muster wie MVC verwenden, die in der Controller oder MVP im Presenter.

Wenn diese Muster nicht verwendet werden, könnten Sie in Betracht ziehen, die Informationen in der Business-Schicht in Sitzung zu setzen, aber nur wenn Sie die Sitzung beenden und diese Abhängigkeit in Ihr Geschäftsobjekt injizieren, z. etwas wie "IUserSession". Das Geschäftsprojekt sollte keinen Verweis auf "system.Web" oder ähnliches enthalten.

+0

Der Schlüsselpunkt hier ist, dass die Ergebnisse der Abfrage (nicht der DAL) in die Sitzung gehen sollten. Das Session-Objekt selbst verfügt bereits über alle gewünschten Eigenschaften: 'Zusätzliche Instanzen werden nicht innerhalb derselben Sitzung erstellt.' (Wenn Sie Ihre Abfrage in einer Frage mit SQL-Tags veröffentlichen, erhalten Sie möglicherweise Hilfe bei der Optimierung. 30 Sekunden sind für eine Webseite zu lang, es sei denn, Ihre Benutzer haben keine andere Wahl, sie zu verwenden.) – mafue

Verwandte Themen