Oracle запрос сработал, затем никогда не возвращается - PullRequest
1 голос
/ 20 июля 2009

У меня есть эта проблема в моем приложении ASP.NET, где я вижу, что некоторые из моих запросов Oracle сработали на сервере, а затем не возвращаются. Когда-либо. Это происходит в нескольких местах в моем приложении, и я не могу это объяснить. Вот один конкретный сценарий, где я вижу это поведение:

Во время запуска приложения я предварительно асинхронно извлекаю данные в состояние приложения (был сделан выбор использовать состояние приложения вместо кэша, так как данные никогда не изменяются в течение времени жизни приложения).

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 я перехожу к инструменту «Мониторинг сеансов» и вижу один сеанс для запроса. Похоже, что он завершен, поскольку время ожидания равно нулю, а сеанс неактивен. Вот код 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 строк. Но часто возникает проблема с запросами, которые никогда не возвращаются, и я не могу отследить эту проблему. У кого-нибудь есть мысли?

И, наконец, поскольку я понимаю, что это может быть что-то совершенно не связанное с кодом, я запускаю приложение локально (из Visual Studio) на компьютере с Windows XP SP3 и подключаюсь через VPN к удаленному экземпляру Oracle 10g Enterprise, работающему в Windows 2003 Сервер. Локально я установил компоненты доступа к данным Oracle v11.1.0.6.20.

Спасибо!

Ответы [ 2 ]

1 голос
/ 20 июля 2009

Следите ли вы за выходным окном за любыми исключениями? Я не вижу никаких блоков catch в вашем коде.

Oracle ODP.net имеет почти такой же синтаксис, что и ADO, но работает лучше во многих ситуациях. Если вы используете только Oracle, возможно, стоит посмотреть.

Есть ли причина использовать StringBuilder? Одна строковая переменная будет работать лучше и облегчит чтение кода.

0 голосов
/ 31 августа 2009

Похоже, что запросы действительно возвращались, что занимало очень много времени из-за низкой производительности запросов, низкой пропускной способности и огромного количества возвращаемых строк. Отладчик VS, похоже, через несколько секунд отказывается от этих длительных запросов. Однако, если я оставлю это на несколько минут, мои контрольные точки будут сбиты, и все будет работать как положено.

Спасибо за ответы / комментарии!

...