1

我在我的 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 Server 上运行的远程 Oracle 10g Enterprise 实例。在本地,我已经安装了 Oracle Data Access Components v11.1.0.6.20。

谢谢!

4

2 回答 2

1

您是否正在查看输出窗口是否有任何异常?我在您的代码中看不到任何 catch 块。

Oracle 的 ODP.net 具有与 ADO 几乎完全相同的语法,但在许多情况下性能更好。如果您只使用 Oracle,则可能值得一看。

有理由使用 StringBuilder 吗?单个字符串变量的性能会更好,并使代码更易于阅读。

于 2009-07-20T11:20:22.713 回答
0

看起来查询实际上正在返回,只是由于查询性能差、带宽低以及返回的行数巨大而需要很长时间。VS 调试器似乎在几秒钟后放弃了这些长时间运行的查询。但是,如果我让它静置几分钟,我的断点就会被击中,事情就会按预期工作。

感谢您的回复/评论!

于 2009-08-31T17:50:51.313 回答