Wir verfügen über einen C# WCF-Webdienst, der auf Windows 2008 SP2/IIS 7 gehostet wird und auf eine Oracle-Datenbank zugreift. Normalerweise Datenzugriff funktioniert gut, aber während des Belastungstests, ist es oft mal aus und Protokolle und Ausnahme sagen:Oracle Data Provider für .NET: Zeitüberschreitung der Verbindungsanforderung
Error occurred when processing XXXXXXXX Web Service
Oracle.DataAccess.Client.OracleException Connection request timed out at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck)
at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src)
at Oracle.DataAccess.Client.OracleConnection.Open()
at MyWorkspace.WorkForceDataAccess.CheckStaffIdInRSW()
at MyWorkspace.MyClass.MyFunction(MyDataType MyData)
die Datenbank abzufragen, verwenden wir so etwas wie dieses:
OracleConnection orConn = new OracleConnection();
orConn.ConnectionString = "user id=xxx; password=xxx; Connection Timeout=600; Max Pool Size=150; data source= (DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = MYHOST.MYDOMAIN.com)(PORT = 1771)) (CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = MYSERVICE.MYDOMAIN.com)))";
orConn.Open();
using (var cmd = new OracleCommand("MY_UTIL.check_StaffIdInRSW", orConn) { CommandType = CommandType.StoredProcedure })
{
cmd.Parameters.Add("P_Staff_Id", OracleDbType.Int32);
cmd.Parameters["P_Staff_Id"].Direction = ParameterDirection.Input;
cmd.Parameters["P_Staff_Id"].Value = Convert.ToInt32(MyDataObject.StaffId);
cmd.Parameters.Add("P_retvalue", OracleDbType.Int32);
cmd.Parameters["P_retvalue"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery(); // Execute the function
//obtain result
returnVal = int.Parse(cmd.Parameters["P_retvalue"].Value.ToString());
}
Ich bin ziemlich zuversichtlich, dass Die gespeicherte Prozedur, die aufgerufen wird, benötigt nicht die ganze Zeit. Es ist eine ziemlich einfache Prozedur, die schnell überprüft, ob die P_Staff_Id in der Tabelle existiert und das Ergebnis zurückgibt.
Zusätzlich tritt dies nur während Belastungstests auf. Während des normalen Betriebs sind die Dinge in Ordnung, aber während schwerer Lasten mit 1 Nachricht pro Sekunde tritt dies auf, nachdem es einige Zeit lang flüssig gelaufen ist.
Als Abhilfe können, ich habe hinzugefügt „Connection Timeout = 600; Max Pool Size = 150“ an die Verbindungszeichenfolge, aber das beheben das Problem nicht
Wir haben die gleiche Anwendung auf einem Entwicklungs-Server ausgeführt wird. und es funktioniert gut. Wir haben dieses Problem nie begegnet.
Irgendwelche Vorschläge, was würde geschätzt, um zu versuchen. es sieht aus wie ich laufe aus Optionen.
Die Stacktrace lassen vermuten, dass das Verfahren nicht das Problem. Die Ausnahme wird vor ihrer Ausführung in Connection.Open ausgelöst. Es sieht daher so aus, als ob der Datenbankcomputer überlastet ist, sodass er nicht innerhalb von Zeitüberschreitungen auf den Client antworten kann. Es sollte nicht mit der Poolgröße oder den Prozesseinschränkungen in Oracle in Verbindung stehen, da diese unterschiedliche Ausnahmen auslösen. Auch würde ich über diese Poolgröße misstrauisch sein, weil es keinen Sinn macht, einen Pool zu haben, der wesentlich größer ist als die Anzahl der Kerne, die die Datenbank verwenden kann. Oder du hast irgendwo einen Verbindungsleck. – Husqvik
Ich habe die Connection Timeout und Max Pool Size zu der Verbindungszeichenfolge hinzugefügt, nachdem dieses Problem aufgetreten ist - aber es hat nicht geholfen. Der Webservice funktionierte ohne diese in der DEV-Umgebung einwandfrei. Würden Sie vorschlagen, das OracleConnection-Objekt nach dem Verbindungsleck explizit zu schließen und zu entfernen, nachdem es verwendet wurde? – DjD
Anzeigenverbindungsverlust - Wenn das Verbindungsobjekt innerhalb einer einzelnen Funktion nur eine kurze Lebensdauer hat, ist die Verwendung von (var connection = ...) {...} definitiv sicherer. Aber ich erwarte nicht, dass dies das Problem ist. Sie würden eine andere Ausnahme erhalten, wenn der Pool vollständig genutzt wird. Adload-Test - Ich erwarte, dass Sie viele Instanzen der Anwendung oder Funktion parallel ausführen. Erwarten Sie außerdem, dass Sie dedizierte Verbindungen und keine gemeinsam genutzten Server als Oracle-Einstellung verwenden. Können Sie überprüfen, wie die Sitzungen während des Tests in der Datenbank aussehen, um zu sehen, wie viele Sitzungen und wie viele aktive Sitzungen tatsächlich dort sind? – Husqvik