Object-Pooling: verliere Verbindung zu Oracle-Datenbank

06/06/2008 - 19:06 von Martin Kissel | Report spam
Hallo zusammen,

ich habe mit .Net 2.0 (C#) eine mehrschichtige Anwendung gebaut, die
sich aufteilt in ein WinForms-Programm (Client) und einen Windows-Dienst
(Server). Client und Server kommunizieren untereinander mittels .Net
Remoting. Das Backend nutzt über System.Data.OracleClient eine
Verbindung auf eine Oracle 10g Datenbank.

Der Client greift auf verschiedene Logik-Klassen auf dem Server zu.
Damit die Nutzung durch mehrere Clients parallel möglich ist, soll beim
Remoting pro Aufruf dank WellKnownObjectMode.SingleCall eine eigene
Instanz der jeweiligen Logik-Klasse erzeugt werden. Diese Logik-Objekte
teilten sich dann ein Datenzugriffs-Objekt, das die Verbindung zur
Datenbank hàlt und als Singleton realisiert ist.

Soweit funktioniert es auch problemlos. Bei mehreren parallelen Nutzern
zeigt sich jedoch, daß das Datenzugriffs-Objekt als Singleton die
Performance bremst. Bei drei Nutzern steigt die Wartezeit bis auf das
dreifache an.

Um dieses Problem zu lösen wollte ich mehrere Datenzugriffs-Objekte
nutzen. Mit jedem Logik-Objekt aber auch ein Datenzugriffs-Objekt zu
erzeugen und anschließend wieder zu entsorgen möchte ich wegen des
Aufwands (Connect zur Datenbank) vermeiden.
Deshalb wollte ich mehrere Datenzugriffs-Objekte in einem Pool
verwalten. Im Konstruktur einer Logik-Klasse holt sie sich ein
Datenzugriffs-Objekt aus dem Pool und gibt es im Destruktur in den Pool
zurück. (Code siehe unten)

Das klappt nach Start des Dienstes für eine Weile auch echt super. Wenn
man aber ne Weile nichts tut funktionieren Abfragen jedoch nur noch
sporadisch - manche Datenzugriffs-Objekte scheinen die Verbindung zur
Datenbank verloren zu haben.
Beim Debuggen fàllt auf, daß das OracleConnection-Objekt con zwar noch
seinen State "Open" hat, statt der ServerVersion jedoch bereits als Text
"con.ServerVersion hat eine Ausnahme vom Typ
System.NullReferenceException verursacht" steht. Sobald ein SQL-Kommando
über dieses OracleConnection-Objekt abgesetzt werden soll, fliegt einem
dann eine Exception um die Ohren: "Der Objektverweis wurde nicht auf
eine Objektinstanz festgelegt."

Was kann die Ursache sein?

Wenn ich nur ein Datenzugriffs-Objekt habe bleibt es auch über Tage noch
mit der Datenbank verbunden, selbst wenn nichts darüber gemacht wird.

Gruß
Martin





class Logik1
{
DB db = DBPool.Instance.GetDB();

public Logik1()
{
}

~Logik1()
{
DBPool.Instance.Release(db);
}

public void tu_was()
{
// Nutzung von db
}
}


class DBPool
// übernommen von http://www.codeproject.com/KB/cs/objectpool.aspx
{
#region Singleton
static DBPool poolInstance = null;
public static DBPool Instance
{
get
{
if (poolInstance == null)
poolInstance = new DBPool(5);
return poolInstance;
}
}
#endregion

Queue myQ = new Queue();
public int Count
{
get { return myQ.Count; }
}

private DBPool(int InitialSize)
{
while (InitialSize > 0)
{
// Create initial objects in the pool
InitialSize--;
myQ.Enqueue(new DB());
}
}

/// <summary>
/// Method to get objects from pool
/// </summary>
public DB GetDB()
{
DB obj;
if (myQ.Count > 0)
{
// Get it from the pool and return.
obj = (DB)myQ.Dequeue();
}
else
{
// No items in pool give a new one..
obj = new DB();
}
return obj;
}

/// <summary>
/// Method to place it back in the pool
/// </summary>
public void Release(DB obj)
{
if (obj != null)
myQ.Enqueue(obj);
}

public void RemoveAll()
{
myQ.Clear();
}
}
 

Lesen sie die antworten

#1 Frank Dzaebel
07/06/2008 - 13:08 | Warnen spam
Hallo Martin,

[...] Client und Server kommunizieren untereinander mittels .Net Remoting.
Das Backend nutzt über System.Data.OracleClient eine Verbindung auf eine
Oracle 10g Datenbank. [...]
Das klappt nach Start des Dienstes für eine Weile auch echt super. Wenn
man aber ne Weile nichts tut, funktionieren Abfragen jedoch nur noch
sporadisch - manche Datenzugriffs-Objekte scheinen die Verbindung zur
Datenbank verloren zu haben.



Du solltest Dir einmal über die Lebensdauer
Deiner Remoting Objekte Gedanken machen:
http://groups.google.com/group/micr...a9256a65a8


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen