コード例 #1
0
        public RelationalDataReader ExecuteReader(RelationalCommandParameterObject parameterObject)
        {
            var connection  = parameterObject.Connection;
            var errorNumber = PreExecution(connection);

            var result = _realRelationalCommand.ExecuteReader(parameterObject);

            if (errorNumber.HasValue)
            {
                connection.DbConnection.Close();
                result.Dispose(); // Normally, in non-test case, reader is disposed by using in caller code
                throw SqlExceptionFactory.CreateSqlException(errorNumber.Value);
            }

            return(result);
        }
コード例 #2
0
        public async Task <object> ExecuteScalarAsync(
            RelationalCommandParameterObject parameterObject,
            CancellationToken cancellationToken = default)
        {
            var connection  = parameterObject.Connection;
            var errorNumber = PreExecution(connection);

            var result = await _realRelationalCommand.ExecuteScalarAsync(parameterObject, cancellationToken);

            if (errorNumber.HasValue)
            {
                connection.DbConnection.Close();
                throw SqlExceptionFactory.CreateSqlException(errorNumber.Value);
            }

            return(result);
        }
コード例 #3
0
        public void Fecha_ShouldReturnDateAfterRecargarFecha()
        {
            //Arrange
            bool     isCorrect = true;
            DateTime Fecha     = new DateTime();

            Mock.Get <ISqlConnectService>(_sqlConnect).SetupSequence(x => x.Execute(It.IsAny <SqlCommand>()))
            .Returns(new DateTime(2020, 01, 24))
            .Returns(new DateTime(2020, 01, 25))
            .Throws(SqlExceptionFactory.NewSqlException())
            .Returns(new DateTime(2020, 02, 10))
            .Returns(new DateTime(2020, 02, 10));

            Queue <DateTime> lista = new Queue <DateTime>();

            lista.Enqueue(new DateTime(2020, 01, 24));
            lista.Enqueue(new DateTime(2020, 01, 25));
            lista.Enqueue(new DateTime(2020, 02, 10));
            lista.Enqueue(new DateTime(2020, 02, 10));

            _sqlDependencyService.CantidadReconecciones = -1;
            _sqlDependencyService.Timeout = 0;

            //Act
            _sqlDependencyService.Start();
            for (int i = 4; i > 0; i--)
            {
                Fecha = _sqlDependencyService.Fecha;

                if (Fecha != lista.Dequeue())
                {
                    isCorrect = false;
                    break;
                }

                _sqlDependencyService.RecargarFecha();
            }

            //Assert
            isCorrect.Should().BeTrue();
        }
コード例 #4
0
        public void Fecha_ShouldReturnDateAfterException(int paramIntentos)
        {
            //Arrange
            Mock.Get <ISqlConnectService>(_sqlConnect).SetupSequence(x => x.Execute(It.IsAny <SqlCommand>()))
            .Throws(SqlExceptionFactory.NewSqlException())
            .Throws(SqlExceptionFactory.NewSqlException())
            .Throws(SqlExceptionFactory.NewSqlException())
            .Returns(new DateTime(2020, 02, 10));

            _sqlDependencyService.CantidadReconecciones = paramIntentos;
            _sqlDependencyService.Timeout = 0;
            DateTime fecha;

            //Act
            _sqlDependencyService.Start();

            fecha = _sqlDependencyService.Fecha;

            //Assert
            fecha.Should().Be(10.February(2020));
        }
コード例 #5
0
    public override void Commit()
    {
        if (_testConnection.CommitFailures.Count > 0)
        {
            var fail = _testConnection.CommitFailures.Dequeue();
            if (fail.HasValue)
            {
                if (fail.Value)
                {
                    this.GetDbTransaction().Rollback();
                }
                else
                {
                    this.GetDbTransaction().Commit();
                }

                _testConnection.DbConnection.Close();
                throw SqlExceptionFactory.CreateSqlException(_testConnection.ErrorNumber, _testConnection.ConnectionId);
            }
        }

        base.Commit();
    }
コード例 #6
0
        private int?PreExecution(IRelationalConnection connection)
        {
            int?errorNumber    = null;
            var testConnection = (TestSqlServerConnection)connection;

            testConnection.ExecutionCount++;
            if (testConnection.ExecutionFailures.Count > 0)
            {
                var fail = testConnection.ExecutionFailures.Dequeue();
                if (fail.HasValue)
                {
                    if (fail.Value)
                    {
                        testConnection.DbConnection.Close();
                        throw SqlExceptionFactory.CreateSqlException(testConnection.ErrorNumber);
                    }

                    errorNumber = testConnection.ErrorNumber;
                }
            }

            return(errorNumber);
        }
コード例 #7
0
    public override async Task CommitAsync(CancellationToken cancellationToken = default)
    {
        if (_testConnection.CommitFailures.Count > 0)
        {
            var fail = _testConnection.CommitFailures.Dequeue();
            if (fail.HasValue)
            {
                if (fail.Value)
                {
                    await this.GetDbTransaction().RollbackAsync(cancellationToken);
                }
                else
                {
                    await this.GetDbTransaction().CommitAsync(cancellationToken);
                }

                await _testConnection.DbConnection.CloseAsync();

                throw SqlExceptionFactory.CreateSqlException(_testConnection.ErrorNumber, _testConnection.ConnectionId);
            }
        }

        await base.CommitAsync(cancellationToken);
    }
コード例 #8
0
 private static SqlException CreateNonTransientException()
 => SqlExceptionFactory.Create(50404);
コード例 #9
0
 private static SqlException CreateTransientException()
 => SqlExceptionFactory.Create(10928);
コード例 #10
0
        public async Task Retries_SaveChanges_on_execution_failure_with_two_contexts(
            bool realFailure,
            bool openConnection,
            bool async)
        {
            CleanContext();

            using (var context = CreateContext())
            {
                using var auditContext = new AuditContext();

                var connection = (TestSqlServerConnection)context.GetService <ISqlServerConnection>();

                connection.ExecutionFailures.Enqueue(new bool?[] { null, realFailure });

                Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State);

                if (openConnection)
                {
                    if (async)
                    {
                        await context.Database.OpenConnectionAsync();
                    }
                    else
                    {
                        context.Database.OpenConnection();
                    }

                    Assert.Equal(ConnectionState.Open, context.Database.GetDbConnection().State);
                }

                context.Products.Add(new Product());
                context.Products.Add(new Product());

                var throwTransientError = true;

                if (async)
                {
                    await new TestSqlServerRetryingExecutionStrategy(context).ExecuteInTransactionAsync(
                        (MainContext: context, AuditContext: auditContext),
                        async(c, ct) =>
                    {
                        var result = await c.MainContext.SaveChangesAsync(false, ct);

                        c.AuditContext.ChangeTracker.Clear();
                        c.AuditContext.Database.SetDbConnection(c.MainContext.Database.GetDbConnection());

                        var currentTransaction = c.AuditContext.Database.CurrentTransaction;
                        if (throwTransientError)
                        {
                            Assert.Null(currentTransaction);
                        }
                        else
                        {
                            Assert.NotNull(currentTransaction);
                        }

                        await c.AuditContext.Database.UseTransactionAsync(
                            c.MainContext.Database.CurrentTransaction !.GetDbTransaction(), ct);

                        Assert.NotSame(currentTransaction, c.AuditContext.Database.CurrentTransaction);

                        await c.AuditContext.Audits.AddAsync(new Audit(), ct);
                        await c.AuditContext.SaveChangesAsync(ct);

                        if (throwTransientError)
                        {
                            throwTransientError = false;
                            throw SqlExceptionFactory.CreateSqlException(10928);
                        }

                        return(result);
                    },
                        (c, _) =>
                    {
                        Assert.True(false);
                        return(Task.FromResult(false));
                    });

                    context.ChangeTracker.AcceptAllChanges();
                }
                else
                {
                    new TestSqlServerRetryingExecutionStrategy(context).ExecuteInTransaction(
                        (MainContext: context, AuditContext: auditContext),
                        c =>
                    {
                        var result = c.MainContext.SaveChanges(false);

                        c.AuditContext.ChangeTracker.Clear();
                        c.AuditContext.Database.SetDbConnection(c.MainContext.Database.GetDbConnection());

                        var currentTransaction = c.AuditContext.Database.CurrentTransaction;
                        if (throwTransientError)
                        {
                            Assert.Null(currentTransaction);
                        }
                        else
                        {
                            Assert.NotNull(currentTransaction);
                        }

                        c.AuditContext.Database.UseTransaction(c.MainContext.Database.CurrentTransaction !.GetDbTransaction());

                        Assert.NotSame(currentTransaction, c.AuditContext.Database.CurrentTransaction);

                        c.AuditContext.Audits.Add(new Audit());
                        c.AuditContext.SaveChanges();

                        if (throwTransientError)
                        {
                            throwTransientError = false;
                            throw SqlExceptionFactory.CreateSqlException(10928);
                        }

                        return(result);
                    },
                        c =>
                    {
                        Assert.True(false);
                        return(false);
                    });

                    context.ChangeTracker.AcceptAllChanges();
                }

                Assert.Equal(openConnection ? 2 : 3, connection.OpenCount);
                Assert.Equal(6, connection.ExecutionCount);

                Assert.Equal(
                    openConnection
                        ? ConnectionState.Open
                        : ConnectionState.Closed, context.Database.GetDbConnection().State);

                if (openConnection)
                {
                    if (async)
                    {
                        await context.Database.CloseConnectionAsync();
                    }
                    else
                    {
                        context.Database.CloseConnection();
                    }
                }

                Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State);
            }

            using (var context = CreateContext())
            {
                Assert.Equal(2, context.Products.Count());
            }
        }
        public async Task GivenANonTransientException_WhenRetryPolicyIsUsed_ThenItShouldNotRetry()
        {
            await Assert.ThrowsAsync <SqlException>(() =>
                                                    _asyncPolicy.ExecuteAsync(() => Task.Run(() => throw SqlExceptionFactory.CreateNonTransientException())));

            Assert.Empty(_capturedRetries);
        }
        public async Task GivenATransientException_WhenRetryPolicyIsUsed_ThenItShouldRetry()
        {
            await Assert.ThrowsAsync <SqlException>(() =>
                                                    _asyncPolicy.ExecuteAsync(() => Task.Run(() => throw SqlExceptionFactory.CreateTransientException())));

            ValidateCapturedRetries();
        }
        public void GivenANonTransientException_WhenCheckedIfExceptionIsTransient_ThenFalseShouldBeReturned()
        {
            SqlException sqlException = SqlExceptionFactory.Create(10001);

            Assert.False(sqlException.IsTransient());
        }
        public void GivenATransientException_WhenCheckedIfExceptionIsTransient_ThenTrueShouldBeReturned(int number)
        {
            SqlException sqlException = SqlExceptionFactory.Create(number);

            Assert.True(sqlException.IsTransient());
        }