IDbConnection Lifecycle Management mit persistenten HTTP-Verbindungen

8

Ich habe ein Problem bei der Verwaltung der Lebensdauer offener Datenbankverbindungen mit StructureMap im Bereich HttpContext , wenn in meiner ASP.NET MVC-Anwendung persistente HTTP-Verbindungen wie SignalR-Hubs bestehen.

Mein DI-Container, StructureMap, fügt eine offene IDbConnection in mehrere Dienste ein. Um sicherzustellen, dass diese Datenbankverbindungen geschlossen und ordnungsgemäß entsorgt werden, rufe ich ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects() für das Ereignis EndRequest auf.

Dies funktioniert hervorragend für MVC-Controller, bis ein Dienst, der eine Datenbankverbindung benötigt, in einen SignalR-Hub eingefügt wird, der eine persistente HTTP-Verbindung für jeden Client offen hält und schließlich den Verbindungspool sättigt.

Wenn ich IDbConnection auf ein Singleton setze, wird immer nur eine Verbindung pro Anwendung geöffnet und der Pool sättigt nicht, aber das ist eine schlechte Idee für den Fall, dass die Verbindung jemals gesperrt wird oder ausläuft.

Vielleicht gibt es eine Möglichkeit, den Umfang der Datenbankverbindungen für meine SignalR-Hubs anzupassen? Ich habe versucht, eine Dienstinstanz in jeder Hub-Methode aufzulösen, aber dies instanziiert weiterhin eine Datenbankverbindung im HttpContext-Bereich und hält sie für die Dauer der Hub-Verbindung des rufenden Clients offen.

Wie sollte ich die Lebensdauer von Datenbankverbindungen mit StructureMap in einem HTTP-Bereich verwalten, wenn persistente HTTP-Verbindungen vorhanden sind?

Beispielcode

Typischer Service

%Vor%

Typischer SignalR Hub

%Vor%

Strukturkartenkonfiguration

%Vor%

Global.asax.cs

%Vor%     
Petrus Theron 08.11.2012, 12:10
quelle

2 Antworten

1

Lösung mit transienter Datenbankverbindung und verschachteltem StructureMap-Container

Konfigurieren Sie zunächst eine benannte, vorübergehende Datenbankverbindungsinstanz in StructureMap:

%Vor%

Stellen Sie sicher, dass Sie vor Ihrer Standardinstanz konfigurieren oder die Standardinstanz überschreiben.

Zweitens, injiziere IContainer in deinen SignalR-Hub, damit du einen verschachtelten StructureMap-Container erstellen kannst:

%Vor%

Instanziieren Sie einen verschachtelten Container in Ihrer SignalR-Methode und lösen Sie Ihre benannte vorübergehende Datenbankverbindung auf:

%Vor%

Verwenden Sie .With<IDbConnection>(transientConnection) , um sicherzustellen, dass Dienste und Repositorys, die von Ihrem geschachtelten Container instanziiert werden, diese Verbindung verwenden:

%Vor%

Schließlich stellt die Bereichsangabe using (...) sicher, dass Ihr geschachtelter Container nach sich selbst aufräumt, einschließlich der Datenbankverbindung.

Der Nachteil hier ist, dass Sie eine Datenbankverbindung für jeden SignalR-Methodenaufruf öffnen und schließen, aber da die Verbindungen gepoolt sind, ist die Freigabe früh möglicherweise nicht so schlecht. Ihr Kilometerstand sollte von Ihrem SignalR-Anfragevolumen abhängen.

Sie können den verschachtelten Container möglicherweise ablegen und einfach DependencyResolver.Current für die benannte Verbindungsinstanz anfordern, aber dann müssen Sie möglicherweise daran denken, jede Verbindung explizit zu schließen, um ein Leck zu vermeiden.

    
Petrus Theron 27.11.2012, 13:46
quelle
1

In SignalR 1.0.0 Alpha, Hub implementiert IDisposable . SignalR Hub Instanzen sind vergänglich im Gegensatz zu HttpContext . Wenn Sie also Ihre IDbConnection in der Methode Hub Dispose schließen, sollten Sie Ihren Verbindungspool nicht unnötig saturieren.

    
halter73 21.11.2012 03:18
quelle