Npgsql连接池在MinPoolSize Connections上停止

时间:2016-07-21 05:41:28

标签: c# postgresql npgsql pooling

第一次使用Npgsql,虽然我已经完成了其他PostgreSQL编程。 Npgsql 3.1.6,PostgreSQL 9.5。 Visual Studio 2015与.Net 4.5.1。

我有一个看起来像这样的连接字符串(每次使用相同的字符串,未经修改,对于每次数据库连接尝试):

  

服务器= DBSERVER; SearchPath中=网络;数据库= NetInfo的;用户   ID = netuser;密码= netpassword;端口= 19491;的CommandTimeout = 300;池=真; MaxPoolSize = 75

这是我们网络的C#多线程数据收集器。收集器上最多运行32个线程。每个线程在需要时打开一个连接,但一次只使用一个连接。如有必要,线程将关闭并重新打开连接。我写了自己的各种连接池,它正在工作;在开始时打开一堆连接,从ConcurrentQueue中拉出一个打开的连接,使用它,然后将其返回到队列中。队列中有16个开放连接。如果做得不对,那就充满了危险但是有效。在代码审查过程中,同事将我转向了Npgsql连接池,所以我正在尝试使用它。

当我到达UPDATE命令System.InvalidOperationException时,我得到"The connection is not open"(dbCommand.ExecuteNonQuery());我不相信命令本身很重要 - 这只是它正在击中的命令。我在DB服务器上注意到netstat显示MinPoolSize + 1个开放套接字。在上面的连接字符串中,它没有定义,因此MinPoolSize是1.我将在netstat中看到两个套接字。如果我将MinPoolSize设置为16,我将看到17个套接字。看起来Npgsql打开最小池大小,然后使用下一个连接抛出InvalidOperationException。但它应该有多达75个连接可用,并在不可用时阻止。不是。

我的PostgreSQL服务器上的最大连接数为100;我远不及那个门槛。

当我使用自编写的池共享方法时,它可以工作,因此执行查询的代码没有问题。这就是我如何获得当前连接。

思考?洞察?谢谢!

编辑:根据要求。 。 。它有点长,但它显示了几个相邻的条件,以了解流量。

lock (ArpTableLocks.GetLock(nd.IdNd + " " + idMi + " " + idIf))
{
    if (_arpTableList.Get(nd.IdNd, idMi, idIf) == null)
    {

        // No device/MAC/IP/intf entry in DB, add one
        var dbConn = new NpgsqlConnection(DBStrings.connectionString);

        var dbCommand = new NpgsqlCommand(DBStrings.sqlARPTableInsert, dbConn);
        dbCommand.Parameters.Add(new NpgsqlParameter("@id_mi", NpgsqlTypes.NpgsqlDbType.Integer, 4));
        dbCommand.Parameters.Add(new NpgsqlParameter("@id_nd", NpgsqlTypes.NpgsqlDbType.Integer, 4));
        dbCommand.Parameters.Add(new NpgsqlParameter("@id_if", NpgsqlTypes.NpgsqlDbType.Integer, 4));
        dbCommand.Parameters["@id_mi"].Value = idMi.ToString();
        dbCommand.Parameters["@id_nd"].Value = nd.IdNd.ToString();
        dbCommand.Parameters["@id_if"].Value = idIf.ToString();
        var dbRead = dbCommand.ExecuteReader();
        dbRead.Read();
        idAt = dbRead.GetInt32(0);
        var arpTableListEntry = new ArpTableEntry
        {
            Id = idAt,
            IdNd = nd.IdNd,
            IdMi = idMi,
            IdIf = idIf
        };
        _arpTableList.Add(arpTableListEntry);

        dbRead.Close();
        dbConn.Close();

    }

}
idAt = (_arpTableList.Get(nd.IdNd, idMi, idIf).Id);

lock (ActiveArpTableLocks.GetLock(nd.IdV + " " + idAt))
{
    if (_activeArpTableList.Get(nd.IdV, idAt) == null)
    {
        var dbConn = new NpgsqlConnection(DBStrings.connectionString);

        NpgsqlCommand dbCommand = new NpgsqlCommand(DBStrings.sqlActiveARPTableInsert, dbConn);
        dbCommand.Parameters.Add(new NpgsqlParameter("@id_v", NpgsqlTypes.NpgsqlDbType.Integer, 4));
        dbCommand.Parameters.Add(new NpgsqlParameter("@id_at", NpgsqlTypes.NpgsqlDbType.Integer, 4));
        dbCommand.Parameters.Add(new NpgsqlParameter("@seen", NpgsqlTypes.NpgsqlDbType.Timestamp));
        dbCommand.Parameters["@id_v"].Value = nd.IdV.ToString();
        dbCommand.Parameters["@id_at"].Value = idAt.ToString();
        dbCommand.Parameters["@seen"].Value = ae.TimeSeen;
        dbCommand.ExecuteNonQuery();

        // Insert a history record
        dbCommand = new NpgsqlCommand(DBStrings.sqlHistoryARPTableInsert, dbConn);
        dbCommand.Parameters.Add(new NpgsqlParameter("@id_v", NpgsqlTypes.NpgsqlDbType.Integer, 4));
        dbCommand.Parameters.Add(new NpgsqlParameter("@id_at", NpgsqlTypes.NpgsqlDbType.Integer, 4));
        dbCommand.Parameters.Add(new NpgsqlParameter("@firstseen", NpgsqlTypes.NpgsqlDbType.Timestamp));
        dbCommand.Parameters["@id_v"].Value = nd.IdV.ToString();
        dbCommand.Parameters["@id_at"].Value = idAt.ToString();
        dbCommand.Parameters["@firstseen"].Value = ae.TimeSeen;
        dbCommand.ExecuteNonQuery(); // Exception thrown here

        dbConn.Close();

        Interlocked.Increment(ref _arpEntryAdded);

    }
    else
    {

        // DB has an active ARP table entry, so update its seen time.
        var dbConn = new NpgsqlConnection(DBStrings.connectionString);

        NpgsqlCommand dbCommand = new NpgsqlCommand(DBStrings.sqlActiveARPTableUpdateSeen, dbConn);
        dbCommand.Parameters.Add(new NpgsqlParameter("@seen", NpgsqlTypes.NpgsqlDbType.Timestamp));
        dbCommand.Parameters.Add(new NpgsqlParameter("@id_v", NpgsqlTypes.NpgsqlDbType.Integer, 4));
        dbCommand.Parameters.Add(new NpgsqlParameter("@id_at", NpgsqlTypes.NpgsqlDbType.Integer, 4));
        dbCommand.Parameters["@seen"].Value = ae.TimeSeen;
        dbCommand.Parameters["@id_v"].Value = nd.IdV.ToString();
        dbCommand.Parameters["@id_at"].Value = idAt.ToString();
        dbCommand.ExecuteNonQuery();

        dbConn.Close();

        // Remove from activearptable hashtable
        _activeArpTableList.Delete(nd.IdV, idAt);
        Interlocked.Increment(ref _arpEntryUpdated);

    }
}

0 个答案:

没有答案