【发布时间】:2017-08-20 16:59:15
【问题描述】:
大家好:我有一个程序运行 4 个与 Oracle 数据库对话的线程。我在每个线程都有本地的 Oracle 连接,并且我正在使用 USING 语句以及手动关闭记录集并关闭连接。据我了解,当打开的记录集多于数据库上配置的游标时,会出现 ORA-01000 错误。我不明白为什么我的记录集保持打开状态或为什么会出现此错误。代码如下:
static void CheckPaths()
{
int pathcount = paths.Count; //paths is a typed list
Parallel.ForEach(paths, new ParallelOptions { MaxDegreeOfParallelism = 4 }, (p) =>
{
try
{
CheckSinglePathAllHours(p);
}
catch (Exception ex)
{
//there is logging here, this is where the exception hits
}
});
}
static void CheckSinglePathAllHours(Path p)
{
string sqlBase = @"Select * from table ";//this is actually a big SQL statement
using (DBManager localdbm = new DBManager())
{
string sql = sqlBase;
OracleDataReader reader = localdbm.GetData(sql);
while (reader.Read())
{
//process the path, query always returns 24 or less rows
}
reader.Close();
reader = null; //is this even necessary?
localdbm.Close(); //is this necessary in conjunction with the USING statement?
}
}
class DBManager : IDisposable
{
OracleConnection conn;
OracleCommand cmd;
public DBManager()
{
string connStr = "blah blah blah";
conn = new OracleConnection(connStr);
conn.Open();
cmd = conn.CreateCommand();
}
public OracleDataReader GetData(string sql)
{
cmd.CommandText = sql;
cmd.CommandTimeout = 900;
return cmd.ExecuteReader();
}
public void RunSQL(string sql)
{
cmd.CommandText = sql;
cmd.CommandTimeout = 900;
cmd.ExecuteNonQuery();
}
public void Close()
{
conn.Close();
}
public void Dispose()
{
try
{
conn.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
代码通常会在异常发生前运行大约一两分钟。异常消息有两个:ORA-00604:递归 SQL 级别 1 发生错误;和 ORA-01000:超出最大打开游标。任何想法我做错了什么?
【问题讨论】:
-
OracleDataReader和OracleConnection实现IDisposable,但您不会在任何地方处理它们。处置 != 关闭。 -
考虑使用 odp.net 和连接池。更多信息请参见here
-
Paul,看起来像在阅读器上调用 .Dispose() 并且连接解决了问题。