我在我的ASP.NET应用程序中遇到这个问题,我看到我的一些Oracle查询被发送到服务器然后没有返回。永远。它发生在我的应用程序的几个地方,我无法解释它。这是我看到这种行为的一个特定场景:
在应用程序启动期间,我将数据异步预取到应用程序状态(选择使用应用程序状态而不是缓存b / c数据在应用程序的生命周期内永远不会更改)。
Action<string, object> AddApplicationState = (string name, object data) =>
{
Application.Lock();
Application.Add(name, data);
Application.UnLock();
};
Func<DataTable> GetFullNames = () => Database.GetAllNames();
Func<DataTable> GetProvinceNames = () => Database.GetProvinceNames();
Func<DataTable> GetTribeNames = () => Database.GetTribeNames();
GetFullNames.BeginInvoke(result => AddApplicationState("AllNames", GetFullNames.EndInvoke(result)), null);
GetProvinceNames.BeginInvoke(result => AddApplicationState("ProvinceNames", GetProvinceNames.EndInvoke(result)), null);
GetTribeNames.BeginInvoke(result => AddApplicationState("TribeNames", GetTribeNames.EndInvoke(result)), null);
第二个两个返回正常,但第一个要么永远不会返回,要么在大约10分钟后返回。在启动Oracle SQL Developer之后,我转到“监视会话”工具,可以看到查询的单个会话。它看起来已经完成,b / c等待时间为(null)且会话处于非活动状态。这是用于查询数据库的ADO.NET代码:
public static DataTable GetAllNames()
{
using (OracleConnection oraconn = GetConnection())
{
using (OracleCommand oracmd = GetCommand(oraconn))
{
var sql = new StringBuilder();
sql.AppendLine("SELECT NAME_ID, NATIVE_NAME, NVL(FREQUENCY,0) \"FREQUENCY\", CULTURE_ID,");
sql.AppendLine("ENGLISH_NAME, REGEXP_REPLACE(ENGLISH_NAME, '[^A-Za-z]', null) \"ENGLISH_NAME_STRIPPED\"");
sql.AppendLine("FROM NAMES");
oracmd.CommandText = sql.ToString();
var orada = new OracleDataAdapter(oracmd);
var dtAllNames = new DataTable();
orada.Fill(dtAllNames);
return dtAllNames;
}
}
}
public static DataTable GetTribeNames()
{
using (OracleConnection oraconn = GetConnection())
{
using (OracleCommand oracmd = GetCommand(oraconn))
{
var sql = new StringBuilder();
sql.AppendLine("SELECT DISTINCT NAME_ID, English_Name \"TRIBE_NAME_ENGLISH\",");
sql.AppendLine("REGEXP_REPLACE(English_Name, '[^A-Za-z]',null) \"TRIBE_ENGLISH_NAME_STRIPPED\",");
sql.AppendLine("NATIVE_NAME \"TRIBE_NATIVE_NAME\"");
sql.AppendLine("FROM NAMES");
sql.AppendLine("WHERE NAME_ID IN ");
sql.AppendLine("(SELECT NAME_ID_TRIBE FROM TRIBES UNION SELECT NAME_ID_FAMILY FROM TRIBES)");
sql.AppendLine("ORDER BY English_Name");
oracmd.CommandText = sql.ToString();
var orada = new OracleDataAdapter(oracmd);
var dt = new DataTable();
orada.Fill(dt);
return dt;
}
}
}
public static DataTable GetProvinceNames()
{
using (OracleConnection oraconn = GetConnection())
{
using (OracleCommand oracmd = GetCommand(oraconn))
{
oracmd.CommandText = "SELECT DISTINCT PROVINCE_ID, PROVINCE_NAME_NATIVE, PROVINCE_NAME_ENGLISH FROM PROVINCES";
var orada = new OracleDataAdapter(oracmd);
var dtRC = new DataTable();
orada.Fill(dtRC);
return dtRC;
}
}
}
正如您所看到的,ADO.NET代码非常标准(而且很无聊!)。在SQL Developer中运行时,查询返回的时间不到一秒。第一个查询返回x行,第二个x行和第三个x行。但是这个查询被解雇然后永远不会返回的问题经常发生,我似乎无法追查这个问题。有人有什么想法吗?
最后,因为我意识到它可能与代码完全无关,我在Windows XP SP3机器上本地运行应用程序(从Visual Studio)并通过VPN连接到在Windows 2003上运行的远程Oracle 10g Enterprise实例服务器。在本地,我安装了Oracle Data Access Components v11.1.0.6.20。
谢谢!
答案 0 :(得分:1)
您是否在观察输出窗口是否有异常?我没有在你的代码中看到任何catch块。
Oracle的ODP.net与ADO的语法几乎完全相同,但在许多情况下表现更好。如果您只使用Oracle,那么可能值得一看。
有没有理由使用StringBuilder?单个字符串变量将表现更好,并使代码更易于阅读。
答案 1 :(得分:0)
似乎查询 实际上正在返回,由于查询性能不佳,带宽较低以及返回的行数量很大,因此需要花费很长时间。对于这些长时间运行的查询,VS调试器似乎会在几秒后放弃。但是,如果我让它静置几分钟,我的断点就会受到影响,事情会按预期运作。
感谢您的回复/评论!