8

我正在尝试使用 ODP.NET 版本 2.111.6.20 为我的 .NET 应用程序配置连接池。数据库是 Oracle 11.1。

我在 .NET 2.0 应用程序中使用以下连接字符串:

Data Source=prod; User Id=FAKE_USER; Password=FAKE_PASS; Pooling=true; Min Pool Size=2; Max Pool Size=5; Connection Timeout=30;"

根据文档,连接池应初始化为 2 个连接,并根据需要最多增加 5 个连接。它永远不应超过 5 个连接。

我所看到的是连接一次增长 2 个,并且增长到 10 个连接。我通过查询 v$session 表来监视 Oracle 数据库中的连接,因此我知道这些连接来自源自我的应用程序的特定应用程序。

如果有人可以帮助我确定此应用程序内的连接池中可能发生的情况,可能允许超过最大连接数,我将不胜感激。

示例 C# 代码

以下是调用数据库的代码示例:

const string connectionString = "Data Source=prod; User Id=FAKE_USER; Password=FAKE_PASS; Pooling=true; Min Pool Size=5; Max Pool Size=5; Connection Timeout=30;";

using (OracleConnection connection = new OracleConnection(connectionString)) {
    connection.Open();

    using (OracleCommand command = new OracleCommand("ALTER SESSION SET TIME_ZONE='UTC'", connection)) {
        command.ExecuteScalar();
    }

    using (OracleTransaction transaction = connection.BeginTransaction()) {
        const string procSql = @"BEGIN P_SERVICES.UPDATE_VERSION(:id, :version, :installDate); END;";
        using (OracleCommand command = new OracleCommand(procSql, connection)) {
            command.Parameters.Add(new OracleParameter("id", OracleDbType.Varchar2) { Value = id });
            command.Parameters.Add(new OracleParameter("version", OracleDbType.Varchar2) { Value = version });
            command.Parameters.Add(new OracleParameter("installDate", OracleDbType.TimeStamp) { Value = dateUpdated });

            try {
                command.ExecuteNonQuery();
            } catch (OracleException oe) {
                if (Log.IsErrorEnabled) {
                    Log.ErrorFormat("Update Error: {0}", oe.Message);
                }

                throw;
            }

            transaction.Commit();
        }
    }
}
4

4 回答 4

13

我发现数据库中看到的最大连接数增加超过连接字符串中连接池设置中允许的数量的原因。

IIS 中的应用程序池配置为“最大工作进程数”设置不同于默认值 1。我发现在数据库中看到的连接数可以增长到Max Pool Size * Number of Worker Processes.

因此,如果我的最大池大小为 5 和 5 个工作进程,则允许的连接总数为 25。所以似乎每个工作进程都有自己的连接池实例,该实例不被其他工作进程共享。

于 2013-04-16T17:12:40.107 回答
4

您可以使用此查询来监控您的连接计数和状态。使用此查询,我能够确认连接字符串设置是否正常工作,解释如下。

select   COUNT(*) AS Connections
        ,s.username
        ,s.status
        ,s.module
        ,s.osuser
from    V$process p
join    V$session s on s.paddr = p.addr
where  NOT s.UserName IS NULL
group by s.username
        ,s.status
        ,s.module
        ,s.osuser

我用 2 个页面运行了这个,这些页面做了一堆数据库检索。这是我的不同结果:

最大池大小=5

最大池大小 = 5

我看到与网络服务器具有相同用户名的空模块下的计数波动。我不确定他们为什么会出现在那个桶和网络服务器下。

最大池大小=1

最大池大小 = 1

当我限制池大小时,我只看到空模块的 1 个连接和 web 服务器的 1 个连接,但随后在 DBMS_SCHEDULER 下弹出连接,这向我表明其余的检索正在等待?

我认为这证明 Max Pool Size 有效,但我不确定。

于 2013-04-13T21:33:23.353 回答
3

根据Tom kyte 的说法:
连接是您和数据库之间的物理电路。
连接可能是多种类型之一——最流行的开始是专用服务器和共享服务器。
可以通过与数据库的给定连接建立零个、一个或多个会话 。会话
将使用进程来执行语句。
有时 CONNECTION->SESSION->PROCESS 之间存在一对一的关系(例如:正常的专用服务器连接)。
有时,从连接到会话是一对多的。
进程不必专用于特定的连接或会话,但是,例如,当使用共享服务器 (MTS) 时,您的 SESSION 将从进程池中获取进程以执行语句。当调用结束时,该进程被释放回进程池。
所以运行
select username from v$session where username is not null 将显示当前的seeions(不是连接)
查看您可能使用的连接

select username, program from v$process;

可以在这里找到一本关于 JDBC 和 Session VS Connection 的有用书籍

于 2013-04-13T18:52:01.923 回答
2

如果您绝对必须解决这个问题,并且愿意对性能计数器感到沮丧,那么这篇博文可能会有所帮助。至少,它可能有助于缩小 Oracle 报告的连接数与 .NET 声称拥有的池化和非池化连接数之间的差异。

http://blog.ilab8.com/2011/09/02/odp-net-pooling-and-connection-request-timed-out/

这些计数器似乎特别有用:

NumberOfActiveConnectionPools
NumberOfActiveConnections
NumberOfFreeConnections
NumberOfInactiveConnectionPools
NumberOfNonPooledConnections
NumberOfPooledConnections
NumberOfReclaimedConnections
NumberOfStasisConnections
于 2013-04-15T01:39:41.203 回答