ADO.NET DbCommand.ExecuteReader挂起某些查询(Oracle XE 11g)

时间:2017-01-03 15:28:11

标签: c# asp.net oracle

我们的客户在发出访问Oracle XE 11g数据库的请求时,我们的C#/ ASP.NET应用程序遇到了一个非常奇怪的问题。这是通过使用ODP.NET NuGet包的ADO.NET上的纯SQL实现的。

我们的应用程序托管在公共服务器上,而这个特定的数据库私密托管在客户的场所。即,我们已获得带有凭据的连接字符串,并且他们已将我们的公共IP列入白名单,以便应用程序查看和与其数据库通信。

该计划大部分时间都完美无缺。但是,有一组查询(实际上是一个参数略有不同的基本查询)导致挂起以下C#代码行:

var reader = cmd.ExecuteReader(CommandBehavior.Default);

SELECT不是微不足道的,但它也不是非常复杂:

SELECT "T00_".*
FROM (
 SELECT ROWNUM "__ROWNUM",
  "T0_".*
 FROM (
  SELECT "T1_"."FIELD1" "F1",
   "T2_"."FIELD2" "F2",
   "T3_"."FIELD3" "F3",
   "T4_"."FIELD4" "F4"
  FROM "TABLE1" "T1_"
  LEFT OUTER JOIN "TABLE2" "T2_" ON ("T1_"."KEY2" = "T2_"."KEY")
  LEFT OUTER JOIN "TABLE3" "T3_" ON ("T1_"."KEY3" = "T3_"."KEY")
  LEFT OUTER JOIN "TABLE4" "T4_" ON ("T1_"."KEY4" = "T4_"."KEY")
  ORDER BY "T1_"."KEY2",
   "T1_"."KEY3"
  ) "T0_"
 ) "T00_"
WHERE "T00_"."__ROWNUM" <= 50

TABLE1中有几百行,上面的SELECT返回50个,如预期的那样。但只是略微改变它,例如请求62行而不是50行,或者将一个JOIN-ed表中的字段添加到ORDER BY,足以导致挂起。没有错误,没有超时 - 调用线程只是永远挂在ExecuteReader行上。

我们已经进行了相当多的实验,但引起这种情况的变化似乎没有什么特别的意义。

客户声称他们的其他(本地)应用程序对此数据库服务器没有任何问题,因此问题必须在我们的应用程序中。我倾向于同意,因为通过TOAD执行时所有查询都运行良好。它们仅在我们的应用程序执行时挂起。我还没能连接点......

令人困惑的部分是,我们的ASP.NET应用程序成功地从许多连接的数据库引擎(包括其他Oracle版本)中为我们的客户检索数据,并且我发现没有这样的问题。

还有其他人通过ADO.NET与Oracle XE有过类似的行为吗?你有什么建议我试试我们的结局?告诉客户切换数据库目前不是一种选择。

1 个答案:

答案 0 :(得分:0)

de OracleCommand类上FetchSize属性的默认值似乎存在问题,导致使用ExecuteReader()函数后导致锁定。 手动更改FetchSize属性可以为我解决此问题:

((OracleCommand)cmd).FetchSize = 1000000;

值1000000使我能够在大约20秒内将100K条记录写入文件。 如果FetchSize值较低(1000-10000),则增加到60-100秒。