0

我正在用 C# 和 POSTGRESQL 开发一个客户端。

它需要解析一些文本并在表中正确插入数据,所以我们有一个解析器,它为每个表提供了一个字典(目前为 4 个)。

所以我们有一个线程,它在队列中插入 ConcurrentQueue 上的那些字典。

现在,我们有两个计时器:

1)每 10 秒提交一个打开的事务并重新创建一个

这些是方法:

    void transactionTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
            try
            {
                Commit();
            }
            catch (Exception ex)
            {
                Logger.Log(Logger.LogType.ERROR, ex);
                Rollback();
            }

            Transaction();
        }
    }
    public void Commit()
    {
        if (trans != null)
        {
            trans.Commit();
            trans.Dispose();
            trans = null;
        }
    }
    public void Transaction()
    {
        if (dbCon == null || (dbCon != null && dbCon.State != ConnectionState.Open))
            dbCon = Connection;

        if (trans == null)
            trans = dbCon.BeginTransaction();
    }
    public void Rollback()
    {
        if (trans != null)
        {
            trans.Rollback();
            trans.Dispose();
            trans = null;
        }
    }

2)在队列中选择一百个数据并使用如下参数进行巨大的插入(不是 100* 插入一个):

    insert into Tabletest1_HandsData( handDataId, handData) values( @handDataId0,   @handData0),( @handDataId1, @handData1),( @handDataId2, @handData2),( @handDataId3, @handData3) ....

通过使用这个助手

    public bool Insert(String tableName, Dictionary<String, object> data, bool usingTransaction = false)
    {
        Boolean returnCode = true;
        var sql = GetSQL(tableName, data);
        try
        {
            int rowsUpdated = -1;
            var conn = (!usingTransaction) ? Connection : dbCon;
            DbCommand mycommand = GetCommand(conn, sql);
            GetCommandByDictionary(mycommand, data);
            rowsUpdated = mycommand.ExecuteNonQuery();
            if (!usingTransaction)
            {
                conn.Close();
                conn.Dispose();
            }
        }
        catch (Exception ex)
        {
            Logger.Log(Logger.LogType.ERROR, ex);
            returnCode = false;
        }
        return returnCode;
    }
    protected override void GetCommandByDictionary(DbCommand cmd, Dictionary<string, object> data)
    {
        foreach (var val in data)
            (cmd as NpgsqlCommand).Parameters.AddWithValue(val.Key.ToString(), val.Value);
    }

因此,我们解析并插入一个队列,然后每 3 秒我们选择其中的 100 个并插入,每 10 秒提交并重新创建一个事务

我的错误是 ExecuteNonQuery 给了我:

    There is already an open DataReader associated with this Command which must be closed first.

为什么会这样?

我可以借此机会问你,我怎样才能做得更好?请随意侮辱我,我已经尝试了很多东西

谢谢卢卡

4

0 回答 0