我们在Windows 2008 SP2/IIS 7上托管的C#WCF Web服务访问Oracle数据库。通常的数据访问工作正常,但负载测试过程中,经常超时和日志和异常说:用于.NET的Oracle数据提供程序:连接请求超时
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)
查询数据库,我们使用这样的事情:
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());
}
我非常有信心被调用的存储过程并不是一直占用的。这是一个非常简单的过程,可以快速检查表中是否存在P_Staff_Id并返回结果。
此外,这仅在负载测试期间发生。在正常的操作过程中,事情没有问题,但是在负载很重的情况下,每秒发送1条消息,这会在运行平稳一段时间后发生。
作为一种变通方法,我已经加入“连接超时= 600;最大池大小= 150“ 到连接字符串,但没有解决问题
我们已经在开发服务器上运行相同的应用程序。它工作正常。我们从来没有遇到过这种问题存在。
任何建议,什么尝试将不胜感激。它看起来像我跑出来的选择。
堆栈跟踪表明,程序不是问题。在Connection.Open内部执行之前引发异常,所以看起来数据库机器已经过载,所以在超时期限内它不能响应客户端。它不应该与Oracle中的池大小或进程限制相关,这些会引发不同的例外。此外,我会怀疑该池的大小,因为将池数量大大超过数据库可以使用的数量是没有意义的。或者你有连接泄漏的地方。 – Husqvik
在发生此问题后,我将连接超时和最大池大小添加到连接字符串 - 但它没有帮助。 Web服务在DEV环境中工作正常,但没有这些。通过连接泄漏,你会建议在使用OracleConnection对象后明确地关闭并处理它吗? – DjD
广告连接泄漏 - 如果连接对象在单个函数中只有短暂生存,那么使用(var connection = ...){...}绝对是更安全的。但我不认为这是问题。当池被完全使用时,你会得到不同的异常。 广告负载测试 - 我期望您可以并行运行应用程序或功能的许多实例。也期望您使用专用连接,而不是Oracle设置的共享服务器。您可以在测试期间检查会话在数据库中的外观,以查看实际有多少会话以及多少个活动会话。 – Husqvik