DevTrain Startseite Visual Studio 1 Magazin  
  
  
SUCHEN:  
ARTIKEL ONLINE: 525   

Kategorien
.NET
Datenbanken
Web
XML

Allgemein
Camp
Foren
Events
Persönliche Einstellungen
Registrieren
Prämien Shop
Kontakt
Impressum
Über DevTrain

Autoren


   Autor: Klaas Wedemeyer Artikel Drucken
        
Schnellere Datenbankzugriffe mit einem ConnectionPool

Wenn mehrere Programmteile unabhängig von einander auf die Datenbank zugreifen, müssen alle eine eigene Verbindung verwenden. Das Öffen und Schließen verbraucht dabei sehr viel Zeit. Das tritt beonders an zwei Stellen deutlich auf:
- In einer Web-Anwendung macht jeder Request seine Zugriffe auf die DB
- In einer komponentenorientierten Anwendung greift jede Komponente selber auf die DB zu (das fällt besonders beim Start auf, wenn sich alle Komponenten intitalisieren).
Die Lösung: Eine zentrale Stelle, die die Verbindungen öffnet, verwaltet und, wenn nicht mehr gebraucht, wieder schließt. Beim Multithreading können gleichzeitig auch mehrere Verbindungen offen sein.
Das ist gar nicht so schwer: Die Anwendung öffnet und schließt die Verbindungen nicht mehr, sondern fordert sie an und gibt sie wieder frei.

IDbConnection Connection = ConnectionPool.Instance.GetConnection(_ConnectionName);
...
ConnectionPool.Instance.ReleaseConnection(Connection)

Der ConnectionPool gibt entweder eine nicht mehr benutzte Verbindung zurück, oder legt eine neue an.

foreach (ConnectionInfo Info in ConnectionInfos)
{
    if (!Info.IsUsed)
    {
        Info.IsUsed = true;
        return Info.GetConnection();
    }
}
ConnectionInfo NewInfo = new ConnectionInfo(IDbConnectionType, ConnectionString);
ConnectionInfos.Add(NewInfo);
return NewInfo.GetConnection();

Bei der Freigabe wird die Verbindung als nicht mehr benutzt gekennzeichnet.

foreach (ConnectionInfo Info in ConnectionInfos)
{
    if (Info.Connection == Connection))
    {
        Info.IsUsed = false;
        Info.LastUsed = DateTime.Now;
        return;
    }
}

Ein Timer überprüft alle Verbindungen regelmäßig, ob sie eine bestimmte Zeit nicht mehr verwendet wurden und schließt sie gegebenenfalls.

for (int i = ConnectionInfos.Count - 1; i >= 0; i-- )
{
    ConnectionInfo Info = ConnectionInfos[i];
    if (!Info.IsUsed)
    {
        TimeSpan s = DateTime.Now.Subtract(Info.LastUsed);
        if (s.TotalSeconds > IdleTime)
        {
            Info.Connection.Close();
            ConnectionInfos.Remove(Info);
        }
    }
}

Um den Zugriff einfacher zu machen, kann man ein neues Verbindungsobjekt erstellen, das im Open die Verbindung anfordert, im Close diese wieder freigibt und alle anderen Aufrufe weiterleitet.

public class SharedConnection : IdbConnection
{
    public void Open()
    {
        Connection = ConnectionPool.Instance.GetConnection(_ConnectionName);
    }

  public void Close()
  {
    ConnectionPool.Instance.ReleaseConnection(Connection);
    Connection = null;
  }

  public IDbTransaction BeginTransaction(IsolationLevel il)
  {
    return Connection.BeginTransaction(il);
  }
  ...
}

So fällt es fast gar nicht auf, das hinter der Verbindung ein ConnectionPool steht.

Den ganzen Code und ein Beispiel findet Ihr auf meiner Homepage www.KlaasWedemeyer.de. Viel Spaß.


DevTrain Camp - Schneller zum .NET 3.5 Developer
 
Verwandte Artikel      Verlinkte Dokumente
    Keine verknüpften Dokumente
    Keine Links vorhanden

  Erfasst am: 06.12.2006
  Gültig bis: 06.03.2007
2 Ratings
Bewertung: 50,0%
schlecht    sehr gut  

 
© Copyright 2007 ppedv AG