我正在用 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.
为什么会这样?
我可以借此机会问你,我怎样才能做得更好?请随意侮辱我,我已经尝试了很多东西
谢谢卢卡