连接池超时

17
在生产服务器上,有时候连接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. 



我搜索了一些解决方案,但没有什么运气。异常很奇怪,没有像Ora-123这样的标识符... 我使用的是OracleDataAccess客户端。有时这个问题会持续5-10秒钟,有时我必须重启IIS(6.1,Windows Server 2008 R2)来解决问题。很令人沮丧... 我不能将池化设置为false,因为我们有一个庞大的网站。有什么解决办法吗?

4个回答

15
我所了解的最常见原因是未能正确处理与Oracle.DataAccess.Client相关的IDisposable对象。
您可能有一些代码没有正确释放某些对象。这将导致Oracle保持对实际未使用的连接进行控制,从而使您在池中运行的可用连接耗尽。重新启动IIS可以解决此问题,因为它会关闭所有这些连接。
仔细检查您的代码,并确保所有IDisposable对象被正确释放或封装在using语句中。

5
我见过的最常见的连接问题是:
  • 应用程序没有关闭连接。这将使用所有可用连接,因此连接会被随机拒绝。最简单的代码解决方案是尽快关闭应用程序的连接(而不是等待变量离开作用域)。在.NET中,“using”语句非常有效。
  • 您的连接池可能需要重新启动。您可以参考此网站了解更多信息:http://docs.oracle.com/cd/E11882_01/java.112/e12265/manage.htm#BABICIII
  • 您的连接池可能不够大(默认最大大小为100)。尝试增加它。

另一个可能有帮助的网站是:http://blog.ilab8.com/2011/09/02/odp-net-pooling-and-connection-request-timed-out/


2
关键是在您的DbContext上调用.Dispose(),或者确保您的容器为您调用.Dispose()(通过重写dispose并确保每个新的DbContext都有相应的调用.Dispose())。
您可能想使用析构函数~MyDbContext()作为一个快速的hack来检查调用Dispose()是否会解决应用程序留下连接打开的问题(即不在您的DbContext上调用Dispose())。
似乎在Oracle提供程序中,您必须自己调用Dispose(或让容器为您调用),否则您将泄漏/耗尽连接。
如果您愿意,我可以提供一些示例代码?

1

确保您没有递归连接到数据库。例如:

// 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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接