Oracle Data Provider для .NET: истекло время ожидания запроса на многопоточность - PullRequest
0 голосов
/ 15 марта 2019

Иногда мы сталкиваемся с подобными исключениями в нашем приложении WebApi с Oracle Poolmanager:

à OracleInternal.ConnectionPool.PoolManager 3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, CriteriaCtx criteriaCtx, String affinityInstanceName, Boolean bForceMatch) à OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, CriteriaCtx criteriaCtx, String affinityInstanceName, Boolean bForceMatch) à OracleInternal.ConnectionPool.OracleConnectionDispenser 3.Get (ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, CriteriaCtx attributeCtx) à Oracle.ManagedDataAccess.Client.OracleConnection.Open ()

Эта проблема воспроизводится с использованием ODP.Net 2.2 в сети 4.5.1 и .net core 2.2.

Вот пример кода для его воспроизведения:

 private static void ParallelConnection(int nbConnection, string connectionString)
    {
        var watch = Stopwatch.StartNew();
        Console.WriteLine($"Testing {nbConnection} Connections");
        var taskList = new List<Task<string>>();
        for (int i = 0; i < nbConnection; i++)
        {
            taskList.Add(OpenConnectionSimple(i + 1, connectionString));
        }
        Task.WaitAll(taskList.ToArray());
        taskList.ForEach(t => Console.WriteLine(t.Result));
        Console.WriteLine($"Total elapsed {watch.ElapsedMilliseconds}");
        Console.ReadLine();
    }

private static async Task<string> OpenConnectionSimple(int index, string connectionString)
    {
        return await Task<string>.Factory.StartNew(() =>
        {
            var error = string.Empty;
            var startTime = DateTime.Now;
            var watch = Stopwatch.StartNew();
            var date = DateTime.MinValue;
            long timeCreated = -1;
            long timeOpen = -1;
            try
            {
                using (var cnx = new OracleConnection(connectionString))
                {
                    timeCreated = watch.ElapsedMilliseconds;
                    cnx.Open();
                    timeOpen = watch.ElapsedMilliseconds;
                    using (var cmd = cnx.CreateCommand())
                    {
                        cmd.CommandType = System.Data.CommandType.Text;
                        cmd.CommandText = "SELECT SYSDATE FROM DUAL";
                        date = (DateTime)cmd.ExecuteScalar();
                    }
                }
            }
            catch (Exception ex)
            {
                error = ex.Message;
            }
            watch.Stop();
            var state = (string.IsNullOrWhiteSpace(error)) ? "OK" : $"KO :{error}";
            return $"[{index}]\t start: {startTime:HH:mm:ss.fff}  duration:{watch.ElapsedMilliseconds}ms\t Ctor Connection:{timeCreated}ms \t open Connection:{timeOpen}ms \t SYSDATE Oracle: {date}\t State:{state}";
        });
    }

Result execution

Как видите, вызов метода ParallelConnectionс 20 соединениями установите 4 первых потока в Timeout по умолчанию на 15 секунд, и время соединения других потоков не является разумным!Обычный обходной путь, найденный в Интернете, заключается в увеличении времени ожидания соединения, но в нашем случае время отклика нашего веб-API не является разумным.

Может ли кто-нибудь объяснить, почему открытие первого соединения в ODP.Net требует такого огромноговремя в многопоточности?Есть ли способ избежать этого исключения тайм-аута соединения в приложении Web Api?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...