public async Task <DbCommandProxy> CreateCommandAsync(ConnectionFactoryParameters parameters, ICommandMetricsReportable?metricsReporter, CancellationToken cancellationToken)
        {
            var(connection, index, payOutNumber) = await this._pool.GetConnectionAsync(
                parameters,
                _maxExecutionTime,
                nameof(GlobalConnectionPoolStrategy),
                cancellationToken)
                                                   .ConfigureAwait(false);

            //ChangeDatabase はあまり対応したくない感じだけど、一応指定されてたらここで反映しよう。
            if (!string.IsNullOrWhiteSpace(this._overriddenDatabaseName) && connection.Connection.Database != this._overriddenDatabaseName)
            {
                await connection.Connection.ChangeDatabaseAsync(this._overriddenDatabaseName, cancellationToken).ConfigureAwait(false);
            }

            var sourceCommand = connection.Connection.CreateCommand();

            var command = new DbCommandProxy(
                connection.Id,
                sourceCommand,
                metricsReporter,
                x =>
            {
                this._workingCommands.TryRemove(x, out _);
                this._pool.ReleaseConnection(index, payOutNumber);
            });

            this._workingCommands.TryAdd(command, true);

            return(command);
        }
        public void Test()
        {
            IDbCommand command = new DbCommandProxy();

            command.CommandText = "SELECT COUNT(*) FROM Person.Address WHERE 1 = 0";
            Assert.AreEqual <int>(0, (int)command.ExecuteScalar());
        }
Beispiel #3
0
        private void OnCommandCompleted(DbCommandProxy command)
        {
            //Get initial connection because DbCommandProxy.Connection is mutable.
            if (!this._workingCommands.TryRemove(command, out var connection))
            {
                return;
            }

            lock (this._reusableConnectionsLock)
            {
                this._reusableConnections.Add(connection);
            }

            //fire and forget.
            Task.Run(async() =>
            {
                await Task.Delay(this._reusableTime).ConfigureAwait(false);

                bool removable;
                lock (this._reusableConnectionsLock)
                {
                    removable = this._reusableConnections.Remove(connection);
                }

                if (removable)
                {
                    connection.Dispose();
                }
            });
        }
Beispiel #4
0
        public async Task <DbCommandProxy> CreateCommandAsync(ConnectionFactoryParameters parameters,
                                                              ICommandMetricsReportable?metricsReporter,
                                                              CancellationToken cancellationToken)
        {
            var connection = this.TryReuse();

            if (connection == null)
            {
                connection = this._factory.CreateConnection(parameters);
                await connection.Connection.OpenAsync(cancellationToken).ConfigureAwait(false);

                if (!string.IsNullOrWhiteSpace(this._overriddenDatabaseName))
                {
                    connection.Connection.ChangeDatabase(this._overriddenDatabaseName !);
                }
            }

            var command = new DbCommandProxy(
                connection.Id,
                connection.Connection.CreateCommand(),
                metricsReporter,
                this.OnCommandCompleted);

            this._workingCommands.TryAdd(command, connection);

            return(command);
        }
Beispiel #5
0
 private void OnCommandCompleted(DbCommandProxy command)
 {
     lock (this._commandQueueLock)
     {
         if (this._commandPreparerQueue.Count > 0)
         {
             var preparer = this._commandPreparerQueue.Dequeue();
             preparer.SetResult(true);
         }
         else
         {
             this._isCommandExecuting = false;
         }
     }
 }
Beispiel #6
0
        public void Test()
        {
            IDbCommand command = new DbCommandProxy();

            command.CommandText = "SELECT COUNT(*) FROM Person.Address WHERE 1 = 0";
            Assert.AreEqual <int>(0, (int)command.ExecuteScalar());
            // 确认是否缓冲机制已经生效
            Assert.AreEqual <int>(1, ((DbCommandProxy)command).CacheCount);
            command.ExecuteScalar();
            // 确认在执行内容不发生变化的情况下,是否代理可以用到缓冲
            Assert.AreEqual <int>(1, ((DbCommandProxy)command).CacheCount);
            // 修正执行SQL
            command.CommandText = "SELECT COUNT(*) FROM Person.Address";
            int firstValue = (int)command.ExecuteScalar();

            // 检查修正执行 SQL 后的缓冲加载情况
            Assert.AreEqual <int>(2, ((DbCommandProxy)command).CacheCount);
            command.CommandText = "SELECT COUNT(*) FROM Person.Address WHERE 1 = 1";
            command.ExecuteScalar();
            // 确认数据缓冲代理的自动更新机制
            Assert.AreEqual <int>(2, ((DbCommandProxy)command).CacheCount);
        }
Beispiel #7
0
        public async Task <DbCommandProxy> CreateCommandAsync(ConnectionFactoryParameters parameters,
                                                              ICommandMetricsReportable metricsReporter,
                                                              CancellationToken cancellationToken)
        {
            var preparer = new TaskCompletionSource <bool>();

            lock (this._commandQueueLock)
            {
                if (!this._isCommandExecuting)
                {
                    this._isCommandExecuting = true;
                    preparer.SetResult(true);
                }
                else
                {
                    this._commandPreparerQueue.Enqueue(preparer);
                }
            }

            await preparer.Task.ConfigureAwait(false);

            var connection = await this.GetConnectionAsync(parameters, cancellationToken).ConfigureAwait(false);

            var sourceCommand = connection.Connection.CreateCommand();

            if (this._transaction != null)
            {
                sourceCommand.Transaction = this._transaction;
            }

            var command = new DbCommandProxy(
                connection.Id,
                sourceCommand,
                metricsReporter,
                this.OnCommandCompleted);

            return(command);
        }
Beispiel #8
0
 public DbTransaction GetTransactionOrNull(DbCommandProxy command)
 => this._transaction;
Beispiel #9
0
 public DbConnection GetConnectionOrNull(DbCommandProxy command)
 => this._connection?.ConnectionWithId.Connection;
 public DbConnection GetConnectionOrNull(DbCommandProxy command)
 {
     //Command.Connection の差し替えには対応しない。
     throw new NotSupportedException();
 }
Beispiel #11
0
 public DbConnection?GetConnectionOrNull(DbCommandProxy command)
 {
     return(this._workingCommands.TryGetValue(command, out var connection) ? connection.Connection : null);
 }