代码之家  ›  专栏  ›  技术社区  ›  Kevin Babcock

Oracle查询已启动,然后再也不会返回

  •  1
  • Kevin Babcock  · 技术社区  · 15 年前

    我在我的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分钟后回来。启动OracleSqlDeveloper之后,我转到“监视会话”工具,可以看到查询的单个会话。它看起来已经完成,b/c等待时间为(空),会话处于非活动状态。以下是用于查询数据库的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开发人员中运行时,查询返回的时间不到一秒钟。第一个查询返回x行、第二个x行和第三个x行。但是,这个问题的查询被解雇,然后再也不会返回经常发生,我似乎无法追踪到这个问题。有人有什么想法吗?

    最后,由于我意识到它可能与代码完全无关,我正在Windows XP SP3计算机上本地(从Visual Studio)运行该应用程序,并通过VPN连接到运行在Windows 2003服务器上的远程Oracle 10g企业实例。在本地,我安装了Oracle数据访问组件v11.1.0.6.20。

    谢谢!

    2 回复  |  直到 15 年前
        1
  •  1
  •   Brad Bruce    15 年前

    您是否在监视输出窗口中有任何异常?我在代码中没有看到任何catch块。

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

    是否有理由使用StringBuilder?一个字符串变量可以更好地执行,并且使代码更容易读取。

        2
  •  0
  •   Kevin Babcock    15 年前

    好像有疑问 实际返回,只是由于查询性能差、带宽低以及返回的行数巨大而花费了很长时间。对于这些长时间运行的查询,VS调试器似乎在几秒钟后就放弃了。然而,如果我让它停留几分钟,我的断点就会被击中,事情会如预期的那样工作。

    感谢您的回复/评论!