Abbiamo un servizio Web WCF C# ospitato su Windows 2008 SP2/IIS 7 che accede a un database Oracle. Di solito l'accesso ai dati funziona bene ma durante le prove di carico, è spesso fuori e registri e un'eccezione dicendo:Provider di dati Oracle per .NET: timeout della richiesta di connessione
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)
per interrogare il database, usiamo qualcosa di simile:
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());
}
Sono abbastanza sicuro che la stored procedure che viene invocata non sta prendendo tutto il tempo. È una procedura piuttosto semplice che controlla rapidamente se P_Staff_Id esiste nella tabella e restituisce il risultato.
Inoltre, ciò si verifica solo durante il test di carico. Durante le normali operazioni le cose vanno bene, ma durante carichi pesanti con 1 messaggio al secondo, questo si verifica dopo aver funzionato per un po 'di tempo.
Per aggirare il problema, ho aggiunto "Timeout connessione = 600; Max Pool Size = 150“ per la stringa di connessione, ma che non ha risolto il problema
Abbiamo la stessa applicazione in esecuzione su un server di sviluppo. e funziona benissimo. non abbiamo mai incontrato questo problema.
eventuali suggerimenti riguardo a che cosa da provare sarebbe apprezzato. sembra che io sono a corto di opzioni.
Lo StackTrace suggeriscono che la procedura non è il problema. L'eccezione viene sollevata prima dell'esecuzione in Connection.Open, quindi sembra che il computer del database sia sovraccarico e non possa rispondere al client entro il periodo di timeout. Non dovrebbe essere correlato alla dimensione del pool o ai limiti dei processi in Oracle, questi generano eccezioni diverse. Inoltre, sarei diffidente riguardo alle dimensioni del pool in quanto non avrebbe senso disporre di un pool notevolmente più grande del numero di core che il database può utilizzare. O hai una perdita di connessione da qualche parte. – Husqvik
Ho aggiunto Timeout connessione e Dimensione massima pool alla stringa di connessione dopo che si è verificato questo problema, ma non è stato di aiuto. Il servizio web funzionava perfettamente nell'ambiente DEV senza questi. Per perdita di connessione, suggeriresti di chiudere e smaltire l'oggetto OracleConnection in modo esplicito dopo che è stato utilizzato? – DjD
Perdita della connessione annuncio: se l'oggetto connessione ha solo un breve live nella singola funzione, utilizzare (var connection = ...) {...} è sicuramente più sicuro. Ma non mi aspetto che questo sia il problema. Si otterrebbe un'eccezione diversa quando il pool è completamente utilizzato. Test carico annunci - Mi aspetto che tu esegua molte istanze dell'applicazione o della funzione in parallelo. Si aspettano inoltre che si utilizzino connessioni dedicate, non server condivisi come impostazione Oracle. Puoi controllare come appaiono le sessioni nel database durante il test per vedere quante sessioni e quante sessioni attive ci sono effettivamente. – Husqvik