在生产服务器上,有时随机连接失败到ORacle数据库。我得到了很多
Oracle.DataAccess.Client.OracleException
Pooled connection request timed out
at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck, Int32 isRecoverable)
at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src)
at Oracle.DataAccess.Client.OracleConnection.Open()
at ws.DataConnection() in path.
我搜索了一些解决方案,但没有运气。奇怪的是,Exception没有像Ora-123那样的标识符......我使用了OracleDataAccess客户端。有时这个问题是5-10秒,有时我必须重新启动IIS(6.1,Windows Server 2008 R2)才能解决问题。令人沮丧...我不能设置pooling = false因为我们有一个庞大的网站。有解决方案吗
我所知道的最常见的原因是无法正确处理与Oracle.DataAccess.Client关联的IDisposable对象。
可能有一些代码没有正确处理某些对象。这将导致Oracle保留实际未使用的连接,从而导致池中的可用连接用完。重新启动IIS解决了它,因为它会杀死所有这些连接。
仔细检查您的代码,确保所有IDisposable对象都正确处理或封装在using语句中。
我见过的最常见的连接问题是:
另一个可能有用的网站是:http://blog.ilab8.com/2011/09/02/odp-net-pooling-and-connection-request-timed-out/
关键是在你的DbContext上调用.Dispose()和/或确保你的容器为你调用.Dispose()(通过重写dispose并确保每个新的DbContext都有相应的.Dispose()调用) 。
您可能希望使用析构函数~MyDbContext()作为快速入侵,只是为了检查调用Dispose()将解决您的应用程序保持连接打开的问题(即不在DbContext上调用Dispose())。
看来,对于Oracle提供程序,您必须自己调用Dispose(或让容器为您执行),否则您将泄漏/用完连接。
如果你愿意,我可以提供一些示例代码吗?
确保您没有递归连接到数据库。如:
// collection to wrap several db records
private List<YourClassItems> list
get
{
if (Session["FOO"] == null)
{
// this method connect to the database
List<YourClass> lst = GetItems();
Session["FOO"] = lst;
return lst;
}
return (List<YourClass>)Session["FOO"];
}
// then we have the GetItems() method
private List<YourClass> GetItems()
{
// get several items from database.
while (read())
{
// assume this row is an item
RowItem i = read.Row;
// THIS might be your problem. It will recursively call this method
yourClassItems.Add(i);
}
//to solve this, create a List<YourClass> tempList and then
//yourClassItems = tempList outside the loop
}