23.3 Verbindungspooling 

Stellen Sie sich eine Datenbank im Internet vor, zum Beispiel für Angebote eines Touristikunternehmens. Innerhalb einer kurzen Zeitspanne werden sich mehrere Anwender über die Angebote informieren wollen. Das ständige Auf- und Abbauen der Verbindungen ist jedoch nachteilig, denn mit jedem Aufbau und Abbau einer physischen Verbindung werden die Ressourcen belastet, was zu einer schlechteren Antwortzeit des Datenbankservers führt.
Um die Leistung von Datenbankanwendungen zu verbessern, unterstützt ADO.NET das Konzept der Verbindungspools. Bisher wurde gesagt, dass der Aufruf der Methode Close die Verbindung zur Datenbank schließt. Ganz exakt stimmt diese Aussage nicht (wenn man von den Standardeinstellungen ausgeht). Close bewirkt lediglich, dass die Verbindung in einen Pool geschoben wird. Die physische Verbindung bleibt auch dann bestehen, wenn das SqlConnection-Objekt aufgegeben wird.
Ein Verbindungspool beherbergt nur Verbindungen, die exakt dieselbe Verbindungszeichenfolge haben. Selbst bei kleinsten Abweichungen wird ein neuer Pool erzeugt. Versucht ein Client, die Verbindung mit einer Datenbank herzustellen, werden zunächst alle vorhandenen Pools nach einer passenden Verbindung durchsucht. Passt eine, wird sie dem anrufenden Client zugeordnet, wenn nicht, wird die angeforderte Verbindung neu erstellt. Der Client bearbeitet auf dieser Verbindung die Daten und kann sie am Ende mit Close wieder aufgeben. In jedem Fall wird die Verbindung danach einem Pool zugeführt.
Für jeden Client, der nicht aus einem vorhandenen Verbindungspool versorgt werden kann, wird eine neue Verbindung erstellt. Bei stark frequentierten Datenbanken führt das auf Dauer zu einem inakzeptablen Anwachsen des Pools. Daher wird eine Verbindung aus dem Pool nach einer bestimmten Zeit der Inaktivität gelöscht, standardmäßig nach circa fünf Minuten.
ADO.NET gestattet es Ihnen, das Poolen der Verbindungen zu steuern, um es möglichst gut den spezifischen Anforderungen anzupassen. Sie können sowohl die maximale als auch die minimale Poolgröße festlegen sowie gepoolte Verbindungen manuell freigeben und das Verbindungspooling sogar deaktivieren.
23.3.1 Beispiel für das Verbindungspooling 

Im folgenden Codefragment wird als Beispiel eine Verbindung zehnmal angefordert:
'...\ADO\Verbindung\Verbindungspooling.vb |
Option Strict On Imports System.Data.Common Imports System.Data.SqlClient Namespace ADO Module Verbindungspooling Sub Test() Dim con As DbConnection = New SqlConnection( _ "Data Source=(local);Initial Catalog=Northwind;" & _ "Integrated Security=sspi") ' Verbindung 10-mal öffnen und schließen For i As Integer = 0 To 9 con.Open() con.Close() System.Threading.Thread.Sleep(100) Next i Console.ReadLine() End Sub End Module End Namespace
Weiter oben in diesem Kapitel haben wir bereits das Tool SQL Server Profiler aus dem SQL Server Management Studio eingesetzt, um uns von den Auswirkungen der Methode Close zu überzeugen. Natürlich spielte auch bei diesen Beispielen das Verbindungspooling eine Rolle, war aber zum grundlegenden Verständnis der Close-Methode nicht erforderlich.
Nun verwenden wir den Profiler, um das Poolen von Verbindungen live zu erleben. In Abbildung 23.3 sehen Sie die Aufzeichnung nach dem Ausführen der Beispielprozedur Verbindungspooling. Obwohl zehnmal eine Verbindung aufgebaut wird, ist dennoch nur ein Login- und ein abschließendes Logout-Ereignis zu sehen. Dies geschieht, weil jede Verbindung nach dem Öffnen und dem sich anschließenden Schließen mit Close zwar aus Sicht des Clients geschlossen wird, tatsächlich jedoch in einen Pool wandert, aus dem sie bei jedem weiteren Schleifendurchlauf mit Open wieder in Anspruch genommen wird.
Abbildung 23.3 Ablaufverfolgungsprotokoll des SQL Server-Profilers beim Poolen
23.3.2 Verbindungspooling deaktivieren 

Standardmäßig ist das Pooling aktiviert. Um es zu deaktivieren, ergänzen Sie die Verbindungszeichenfolge wie folgt:
Dim con As DbConnection = New SqlConnection("Data Source=wsak\\SQL2005;" & _
"Initial Catalog=Northwind;Integrated Security=sspi;" & _
"Pooling=False")
Wenn Sie die Verbindungszeichenfolge mit einem SqlConnectionStringBuilder-Objekt erzeugen, legen Sie dessen Eigenschaft Pooling auf False fest.
Im SQL Server Profiler kann das Abschalten des Poolings wieder anschaulich nachverfolgt werden. Für jedes Verbindungsgesuch wird ein Login- und ein Logout-Ereignis protokolliert, wie Abbildung 23.4 zeigt.
Abbildung 23.4 Ablaufverfolgungsprotokoll des SQL Server-Profilers bei abgeschaltetem Poolen
23.3.3 Verbindungspoolgröße manipulieren 

Sowohl die Maximalgröße als auch die Minimalgröße eines Verbindungspools lassen sich steuern. Der Standard für die Minimalgröße ist 0, für die Maximalgröße sind 100 gepoolte Verbindungen vorsehen.
Betrachten wir zuerst die Minimalgröße etwas genauer, hier mit dem Wert 10. Die ersten 10 parallelen Verbindungen lassen den Pool auf 10 Verbindungen anwachsen. Diese bedienen eventuell anfordernde Clients. Sind mehr Verbindungen notwendig, wird der Pool vergrößert, aber die Mindestanzahl wird nicht mehr unterschritten, auch wenn zeitweise keine Verbindung mehr benötigt wird. Die Lebensdauer von ca. fünf Minuten, die ansonsten für gepoolte Verbindungen gilt, betrifft nicht die zehn Verbindungen, die zur Sicherung der Mindestpoolgröße erforderlich sind.
Die Festlegung der Maximalpoolgröße begrenzt die Auslastung eines Datenbankservers. Angenommen, zu einem gegebenen Zeitpunkt ist der Pool ausgeschöpft, weil alle darin enthaltenen Verbindungen aktiv von Clients beansprucht werden. Kommt es dann zu einem weiteren Verbindungsgesuch, wird versucht, innerhalb der Zeitspanne, die in Connect Timeout festgelegt ist, dem anfordernden Client eine Verbindung bereitzustellen. Gelingt das nicht, wird eine InvalidOperationException ausgelöst.
Zur Festlegung der minimalen und maximalen Verbindungspoolgröße dienen uns wieder zwei Attribute in der Verbindungszeichenfolge: Min Pool Size und Max Pool Size. Passend dazu werden von einem SqlConnectionStringBuilder-Objekt die beiden Eigenschaften MinPoolSize und MaxPoolSize angeboten.
Dim con As DbConnection = New SqlConnection( _ "Data Source=wsak\\SQL2005;Initial Catalog=Northwind;" & _ "Integrated Security=sspi;" & _ "Min Pool Size=5;Max Pool Size=200")
23.3.4 Freigabe gepoolter Verbindungen 

Gepoolte Verbindungen können mit den beiden statischen Methoden ClearPool und ClearAllPools freigegeben werden. ClearPool wird ein SqlConnection-Objekt übergeben:
SqlConnection.ClearPool(con)
Das Connection-Objekt ist notwendig, um über dessen Verbindungszeichenfolge den Pool zu bestimmen, in dem Verbindungen aufgegeben werden sollen. Es werden ausschließlich inaktive Verbindungen entfernt, von Clients aktuell beanspruchte bleiben erhalten.
Die parameterlose Methode ClearAllPools löscht alle freien Verbindungen in den Pools.