Oracle Managed DataAccess 连接对象保持连接打开

Oracle Managed DataAccess connection object is keeping the connection open

我正在使用 Oracle.ManagedDataAccess Nuget 包版本 18.3.0。我尝试了很多东西。我试图处理我能想到的所有东西,甚至是 oracle 参数对象。并将所有内容包装在 using 块中但无济于事。唯一真正对我有用的是注释行 OracleConnection.ClearPool(oracle);。这是一个错误,还是一些与配置相关的问题,还是我误解了这里的内容?此外,我尝试删除 Oracle.ManagedDataAccess 的引用并将其替换为 System.Data.OracleClient 的引用,这实际上对我有用。它自动关闭了连接,因此没有连接处于 "In-Active" 状态。下面的代码我将它移到了一个简单的单个按钮中,Windows 表单应用程序可以 100% 确保没有任何干扰并且问题仍然存在。

using (var oracle = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost)(PORT=SomePortHere))(CONNECT_DATA=(SERVER=SHARED)(SERVICE_NAME=anotherHost)))", new OracleCredential(userName,password)))
                {
                    oracle.Open();
                    using (var command = new OracleCommand())
                    {
                        var query = "SELECT x from y where z=:param1";
                        command.Connection = oracle;
                        command.CommandText = query;
                        command.CommandType = System.Data.CommandType.Text;
                        var param1 = new OracleParameter(":param1", xyz);
                        command.Parameters.Add(param1);
                        using (var reader = command.ExecuteReader())
                        {
                            if (reader.Read())
                            {
                                //read the data from the reader
                            }
                        }
                        param1.Dispose();
                    }
                    //If this line is commented, there will be a connection left open, with InActive status
                    //OracleConnection.ClearPool(oracle);
                }
                password.Dispose();
                return myData;

这是一张显示通过 Toad 打开的连接的图像。
当然,每次单击该按钮,上面的代码都会执行,并且新会话将保持打开状态,直到您在图像中看到。 名称 "TheTesterOfAllTests.exe" 是 Windows 表单应用程序。
这是配置问题吗? 除了使用 ClearPool 方法之外,还有什么方法可以解决这个问题吗?因为它会影响应用程序的性能。
P.S。最初使用上述代码的应用程序是一个被 Web 应用程序使用的 WCF Service
P.S。 2 存在某种内存泄漏,每次单击该按钮都会增加内存使用量

事实证明,问题出在 oracle 内部创建连接的方式上,因为对于每个新创建的 OracleConnection 对象,都会将一个新的连接添加到连接池中。我统计了连接池中的 91 个连接条目。 解决方案是为每个请求 "Per Request Scope" 使用一个 OracleConnection 实例。我通过使用一个简单的通用 IDatabase<TConnection> 接口和一个 TConnection GetConnection<TConnection>() 方法实现了这一点,当然对于将在同一请求实例上调用的每个方法,将进行一对 Open/Close 调用所以我们不会一直保持连接打开。
关于内存泄漏,我仍然无法 100% 证实这一点,但是当我使用 Oracle.DataAccess.Client 库而不是 Oracle.ManagedDataAccess 时,内存使用量急剧减少。所以,我切换回 Oracle.DataAccess.Client.

P.S. 如果有关于这两个问题的新信息,我会更新这个答案,非常欢迎贡献,也许我对 Oracle 如何处理有一些误解与数据库连接。

我运行陷入同样的​​问题。 我通过更改 OracleConnection 的初始化解决了它。

来自

var con = new OracleConnection(
    "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost)(PORT=SomePortHere))(CONNECT_DATA=(SERVER=SHARED)(SERVICE_NAME=anotherHost)))",
    new OracleCredential(userName,password));

var con = new OracleConnection(
    "USER ID=myuser;PASSWORD=mypwd;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost)(PORT=SomePortHere))(CONNECT_DATA=(SERVER=SHARED)(SERVICE_NAME=anotherHost)))");

对我来说,这种不同的行为看起来像是一个错误。

因此,我无法再使用 OracleCredential,必须将密码存储为字符串。这对我来说没问题。

备注:SecureString shouldn't be used