public async Task ExecuteAsync_calls_Commit_if_no_transaction() { var mockModificationCommandBatch = new Mock <ModificationCommandBatch>(); var transactionMock = new Mock <RelationalTransaction>(); var mockRelationalConnection = new Mock <IRelationalConnection>(); RelationalTransaction currentTransaction = null; mockRelationalConnection.Setup(m => m.BeginTransaction()).Returns(() => currentTransaction = transactionMock.Object); mockRelationalConnection.Setup(m => m.Transaction).Returns(() => currentTransaction); var cancellationToken = new CancellationTokenSource().Token; var relationalTypeMapper = new RelationalTypeMapper(); var batchExecutor = new BatchExecutorForTest(relationalTypeMapper); await batchExecutor.ExecuteAsync(new[] { mockModificationCommandBatch.Object }, mockRelationalConnection.Object, cancellationToken); mockRelationalConnection.Verify(rc => rc.OpenAsync(cancellationToken)); mockRelationalConnection.Verify(rc => rc.Close()); transactionMock.Verify(t => t.Commit()); mockModificationCommandBatch.Verify(mcb => mcb.ExecuteAsync( It.IsAny <RelationalTransaction>(), relationalTypeMapper, It.IsAny <DbContext>(), null, cancellationToken)); }
public void GetDbTransaction_returns_the_DbTransaction() { var dbConnection = new FakeDbConnection(ConnectionString); var dbTransaction = new FakeDbTransaction(dbConnection); var connection = new FakeRelationalConnection( CreateOptions((FakeRelationalOptionsExtension) new FakeRelationalOptionsExtension().WithConnection(dbConnection))); var loggerFactory = new ListLoggerFactory(); var transaction = new RelationalTransaction( connection, dbTransaction, new Guid(), new DiagnosticsLogger <DbLoggerCategory.Database.Transaction>( loggerFactory, new LoggingOptions(), new DiagnosticListener("Fake"), new TestRelationalLoggingDefinitions(), new NullDbContextLogger()), false, new RelationalSqlGenerationHelper( new RelationalSqlGenerationHelperDependencies())); Assert.Equal(dbTransaction, transaction.GetDbTransaction()); }
public override int Execute( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILogger logger) { Check.NotNull(transaction, nameof(transaction)); Check.NotNull(typeMapper, nameof(typeMapper)); Check.NotNull(context, nameof(context)); Check.NotNull(logger, nameof(logger)); var commandText = GetCommandText(); using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout)) { if (logger.IsEnabled(LogLevel.Verbose)) { // RelationalLoggerExtensions.LogCommand can't be called because the class // is internal... //logger.LogCommand(storeCommand); } try { using (var reader = storeCommand.ExecuteReader()) { var actualResultSetCount = 0; do { actualResultSetCount++; }while (reader.NextResult()); Debug.Assert(actualResultSetCount == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + actualResultSetCount); if (reader.RecordsAffected != ModificationCommands.Count) { throw new DbUpdateConcurrencyException( Microsoft.Data.Entity.Relational.Strings.UpdateConcurrencyException(ModificationCommands.Count, reader.RecordsAffected), context, new List <InternalEntityEntry>() // TODO ); } } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Microsoft.Data.Entity.Relational.Strings.UpdateStoreException, context, ex, new InternalEntityEntry[0]); } } return(ModificationCommands.Count); }
public virtual async Task <int> ExecuteAsync( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(transaction, "transaction"); Check.NotNull(typeMapper, "typeMapper"); using (var storeCommand = CreateStoreCommand(transaction.DbTransaction, typeMapper)) { var commandIndex = 0; try { using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false)) { do { var tableModification = ModificationCommands[commandIndex]; if (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) { if (tableModification.RequiresResultPropagation) { tableModification.PropagateResults(new RelationalTypedValueReader(reader)); } else { var rowsAffected = reader.GetFieldValue <int>(0); if (rowsAffected != 1) { throw new DbUpdateConcurrencyException(string.Format(Strings.FormatUpdateConcurrencyException(1, rowsAffected)), tableModification.StateEntries); } } } else { throw new DbUpdateConcurrencyException(string.Format(Strings.FormatUpdateConcurrencyException(1, 0)), tableModification.StateEntries); } commandIndex++; }while (await reader.NextResultAsync(cancellationToken).ConfigureAwait(false)); } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Strings.FormatUpdateStoreException(), ex, commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].StateEntries : null); } } // TODO Return the actual results once we can get them return(1); }
public override Task <int> ExecuteAsync( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILogger logger, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException("No async here yet"); }
public virtual async Task <int> ExecuteAsync( [NotNull] IEnumerable <ModificationCommandBatch> commandBatches, [NotNull] RelationalConnection connection, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(commandBatches, "commandBatches"); Check.NotNull(connection, "connection"); var rowsAffected = 0; await connection.OpenAsync(cancellationToken).ConfigureAwait(false); RelationalTransaction startedTransaction = null; try { if (connection.Transaction == null) { startedTransaction = connection.BeginTransaction(); } foreach (var commandbatch in commandBatches) { rowsAffected += await commandbatch.ExecuteAsync( connection.Transaction, _typeMapper, _context, Logger, cancellationToken : cancellationToken) .ConfigureAwait(false); } if (startedTransaction != null) { startedTransaction.Commit(); } } catch { if (connection.Transaction != null) { connection.Transaction.Rollback(); } throw; } finally { if (startedTransaction != null) { startedTransaction.Dispose(); } connection.Close(); } return(rowsAffected); }
public virtual int Execute( [NotNull] IEnumerable <ModificationCommandBatch> commandBatches, [NotNull] RelationalConnection connection) { Check.NotNull(commandBatches, "commandBatches"); Check.NotNull(connection, "connection"); var rowsAffected = 0; connection.Open(); RelationalTransaction startedTransaction = null; try { if (connection.Transaction == null) { startedTransaction = connection.BeginTransaction(); } foreach (var commandbatch in commandBatches) { rowsAffected += commandbatch.Execute( connection.Transaction, _typeMapper, _context, Logger); } if (startedTransaction != null) { startedTransaction.Commit(); } } catch { if (connection.Transaction != null) { connection.Transaction.Rollback(); } throw; } finally { if (startedTransaction != null) { startedTransaction.Dispose(); } connection.Close(); } return(rowsAffected); }
public void GetDbTransaction_returns_the_DbTransaction() { var dbConnection = new FakeDbConnection(ConnectionString); var dbTransaction = new FakeDbTransaction(dbConnection); var connection = new FakeRelationalConnection( CreateOptions(new FakeRelationalOptionsExtension { Connection = dbConnection })); var transaction = new RelationalTransaction( connection, dbTransaction, new ListLogger(new List<Tuple<LogLevel, string>>()), false); Assert.Equal(dbTransaction, transaction.GetDbTransaction()); }
public static void ExplicitTransactionTwoSaveChanges() { CUI.MainHeadline(nameof(ExplicitTransactionTwoSaveChanges)); using (var ctx = new WWWingsContext()) { // Start transaction. Default is System.Data.IsolationLevel.ReadCommitted using (var t = ctx.Database.BeginTransaction(System.Data.IsolationLevel.ReadCommitted)) { // Print isolation level RelationalTransaction rt = t as RelationalTransaction; DbTransaction dbt = rt.GetDbTransaction(); Console.WriteLine("Transaction with Level: " + dbt.IsolationLevel); // Read data int flightNo = ctx.FlightSet.OrderBy(x => x.FlightNo).FirstOrDefault().FlightNo; var f = ctx.FlightSet.Where(x => x.FlightNo == flightNo).SingleOrDefault(); Console.WriteLine("Before: " + f.ToString()); // Change data and save f.FreeSeats--; var count1 = ctx.SaveChanges(); Console.WriteLine("Number of saved changes: " + count1); // Change data again and save f.Memo = "last changed at " + DateTime.Now.ToString(); var count2 = ctx.SaveChanges(); Console.WriteLine("Number of saved changes: " + count2); Console.WriteLine("Commit or Rollback? 1 = Commit, other = Rollback"); var eingabe = Console.ReadKey().Key; if (eingabe == ConsoleKey.D1) { t.Commit(); Console.WriteLine("Commit done!"); } else { t.Rollback(); Console.WriteLine("Rollback done!"); } Console.WriteLine("After in RAM: " + f.ToString()); ctx.Entry(f).Reload(); Console.WriteLine("After in DB: " + f.ToString()); } } }
public void GetDbTransaction_returns_the_DbTransaction() { var dbConnection = new FakeDbConnection(ConnectionString); var dbTransaction = new FakeDbTransaction(dbConnection); var connection = new FakeRelationalConnection( CreateOptions((FakeRelationalOptionsExtension) new FakeRelationalOptionsExtension().WithConnection(dbConnection))); var transaction = new RelationalTransaction( connection, dbTransaction, new InterceptingLogger <LoggerCategory.Database.Transaction>(new ListLoggerFactory(new List <Tuple <LogLevel, string> >()), new LoggingOptions()), new DiagnosticListener("Fake"), false); Assert.Equal(dbTransaction, transaction.GetDbTransaction()); }
public void GetDbTransaction_returns_the_DbTransaction() { var dbConnection = new FakeDbConnection(ConnectionString); var dbTransaction = new FakeDbTransaction(dbConnection); var connection = new FakeRelationalConnection( CreateOptions(new FakeRelationalOptionsExtension { Connection = dbConnection })); var transaction = new RelationalTransaction( connection, dbTransaction, new ListLogger(new List <Tuple <LogLevel, string> >()), false); Assert.Equal(dbTransaction, transaction.GetDbTransaction()); }
public virtual async Task <int> ExecuteAsync( [NotNull] IEnumerable <ModificationCommandBatch> commandBatches, [NotNull] IRelationalConnection connection, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(commandBatches, nameof(commandBatches)); Check.NotNull(connection, nameof(connection)); var rowsAffected = 0; await connection.OpenAsync(cancellationToken).WithCurrentCulture(); RelationalTransaction startedTransaction = null; try { if (connection.Transaction == null) { startedTransaction = connection.BeginTransaction(); } foreach (var commandbatch in commandBatches) { rowsAffected += await commandbatch.ExecuteAsync( connection.Transaction, _typeMapper, _context, Logger, cancellationToken) .WithCurrentCulture(); } startedTransaction?.Commit(); } finally { startedTransaction?.Dispose(); connection.Close(); } return(rowsAffected); }
public virtual int Execute( IEnumerable <ModificationCommandBatch> commandBatches, IRelationalConnection connection) { Check.NotNull(commandBatches, nameof(commandBatches)); Check.NotNull(connection, nameof(connection)); var rowsAffected = 0; connection.Open(); RelationalTransaction startedTransaction = null; try { if (connection.Transaction == null) { startedTransaction = connection.BeginTransaction(); } foreach (var commandbatch in commandBatches) { rowsAffected += commandbatch.Execute( connection.Transaction, _typeMapper, _context, Logger); } startedTransaction?.Commit(); } finally { startedTransaction?.Dispose(); connection.Close(); } return(rowsAffected); }
protected virtual void ExecuteStatementsWithinTransaction( [NotNull] IEnumerable <SqlBatch> sqlStatements, [NotNull] RelationalConnection connection) { Check.NotNull(sqlStatements, "sqlStatements"); Check.NotNull(connection, "connection"); RelationalTransaction transaction = null; try { transaction = connection.BeginTransaction(IsolationLevel.Serializable); SqlExecutor.ExecuteNonQuery(connection, transaction.DbTransaction, sqlStatements); transaction.Commit(); } finally { if (transaction != null) { transaction.Dispose(); } } }
public virtual IDbContextTransaction UseTransaction(DbTransaction transaction) { if (transaction == null) { if (CurrentTransaction != null) { CurrentTransaction = null; Close(); } } else { if (CurrentTransaction != null) { throw new InvalidOperationException(RelationalStrings.TransactionAlreadyStarted); } Open(); CurrentTransaction = new RelationalTransaction(this, transaction, _logger, transactionOwned: false); } return CurrentTransaction; }
public override async Task <int> ExecuteAsync( RelationalTransaction transaction, RelationalTypeMapper typeMapper, DbContext context, ILogger logger, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(transaction, nameof(transaction)); Check.NotNull(typeMapper, nameof(typeMapper)); Check.NotNull(context, nameof(context)); Check.NotNull(logger, nameof(logger)); var commandText = GetCommandText(); Debug.Assert(ResultSetEnds.Count == ModificationCommands.Count); var commandIndex = 0; using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout)) { if (logger.IsEnabled(LogLevel.Verbose)) { logger.LogCommand(storeCommand); } try { using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).WithCurrentCulture()) { var actualResultSetCount = 0; do { commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation ? await ConsumeResultSetWithPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture() : await ConsumeResultSetWithoutPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture(); actualResultSetCount++; }while (commandIndex < ResultSetEnds.Count && await reader.NextResultAsync(cancellationToken).WithCurrentCulture()); Debug.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex); #if DEBUG var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e); expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0; Debug.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount); #endif } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Strings.UpdateStoreException, context, ex, commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].Entries : new InternalEntityEntry[0]); } } return(commandIndex); }
public override async Task <int> ExecuteAsync( RelationalTransaction transaction, RelationalTypeMapper typeMapper, DbContext context, ILogger logger, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(transaction, "transaction"); Check.NotNull(typeMapper, "typeMapper"); Check.NotNull(context, "context"); Check.NotNull(logger, "logger"); if (logger.IsEnabled(TraceType.Verbose)) { // TODO: Write parameter values logger.WriteSql(_sql); } var totalRowsAffected = 0; using (var storeCommand = CreateStoreCommand(transaction.DbTransaction, typeMapper)) { var commandIndex = 0; try { using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false)) { do { var tableModification = ModificationCommands[commandIndex]; if (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) { if (tableModification.RequiresResultPropagation) { tableModification.PropagateResults(new RelationalTypedValueReader(reader)); totalRowsAffected++; } else { var rowsAffected = reader.GetFieldValue <int>(0); if (rowsAffected != 1) { throw new DbUpdateConcurrencyException( Strings.FormatUpdateConcurrencyException(1, rowsAffected), context, tableModification.StateEntries); } totalRowsAffected += rowsAffected; } } else { throw new DbUpdateConcurrencyException( Strings.FormatUpdateConcurrencyException(1, 0), context, tableModification.StateEntries); } commandIndex++; }while (await reader.NextResultAsync(cancellationToken).ConfigureAwait(false)); } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Strings.FormatUpdateStoreException(), context, ex, commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].StateEntries : null); } } return(totalRowsAffected); }
private IDbContextTransaction BeginTransactionWithNoPreconditions(IsolationLevel isolationLevel) { Check.NotNull(_logger, nameof(_logger)); _logger.LogDebug( RelationalLoggingEventId.BeginningTransaction, isolationLevel, il => RelationalStrings.RelationalLoggerBeginningTransaction(il.ToString("G"))); CurrentTransaction = new RelationalTransaction( this, DbConnection.BeginTransaction(isolationLevel), _logger, transactionOwned: true); return CurrentTransaction; }
public abstract Task <int> ExecuteAsync( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILogger logger, CancellationToken cancellationToken = default(CancellationToken));
private RelationalTransaction BeginTransactionWithNoPreconditions(IsolationLevel isolationLevel) { Transaction = new RelationalTransaction(this, DbConnection.BeginTransaction(isolationLevel), transactionOwned: true); return Transaction; }
public abstract int Execute( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILogger logger);
public virtual RelationalTransaction UseTransaction([CanBeNull] DbTransaction transaction) { if (transaction == null) { if (Transaction != null) { Transaction = null; Close(); } } else { if (Transaction != null) { throw new InvalidOperationException(Strings.FormatTransactionAlreadyStarted()); } Open(); Transaction = new RelationalTransaction(this, transaction, transactionOwned: false); } return Transaction; }
public override int Execute( RelationalTransaction transaction, RelationalTypeMapper typeMapper, DbContext context, ILogger logger) { Check.NotNull(transaction, "transaction"); Check.NotNull(typeMapper, "typeMapper"); Check.NotNull(context, "context"); Check.NotNull(logger, "logger"); var commandText = GetCommandText(); if (logger.IsEnabled(LogLevel.Verbose)) { // TODO: Write parameter values logger.WriteSql(commandText); } Debug.Assert(ResultSetEnds.Count == ModificationCommands.Count); var commandIndex = 0; using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout)) { try { using (var reader = storeCommand.ExecuteReader()) { var actualResultSetCount = 0; do { commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation ? ConsumeResultSetWithPropagation(commandIndex, reader, context) : ConsumeResultSetWithoutPropagation(commandIndex, reader, context); actualResultSetCount++; }while (commandIndex < ResultSetEnds.Count && reader.NextResult()); Debug.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex); #if DEBUG var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e); expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0; Debug.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount); #endif } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Strings.UpdateStoreException, context, ex, commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].StateEntries : new StateEntry[0]); } } return(commandIndex); }
public override async Task<int> ExecuteAsync( RelationalTransaction transaction, RelationalTypeMapper typeMapper, DbContext context, ILogger logger, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(transaction, nameof(transaction)); Check.NotNull(typeMapper, nameof(typeMapper)); Check.NotNull(context, nameof(context)); Check.NotNull(logger, nameof(logger)); var commandText = GetCommandText(); Debug.Assert(ResultSetEnds.Count == ModificationCommands.Count); var commandIndex = 0; using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout)) { if (logger.IsEnabled(LogLevel.Verbose)) { logger.LogCommand(storeCommand); } try { using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).WithCurrentCulture()) { var actualResultSetCount = 0; do { commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation ? await ConsumeResultSetWithPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture() : await ConsumeResultSetWithoutPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture(); actualResultSetCount++; } while (commandIndex < ResultSetEnds.Count && await reader.NextResultAsync(cancellationToken).WithCurrentCulture()); Debug.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex); #if DEBUG var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e); expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0; Debug.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount); #endif } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Strings.UpdateStoreException, context, ex, commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].Entries : new InternalEntityEntry[0]); } } return commandIndex; }
public override async Task <int> ExecuteAsync( RelationalTransaction transaction, RelationalTypeMapper typeMapper, DbContext context, ILogger logger, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(transaction, "transaction"); Check.NotNull(typeMapper, "typeMapper"); Check.NotNull(context, "context"); Check.NotNull(logger, "logger"); var commandText = GetCommandText(); if (logger.IsEnabled(TraceType.Verbose)) { // TODO: Write parameter values logger.WriteSql(commandText); } Contract.Assert(ResultSetEnds.Count == ModificationCommands.Count); var commandIndex = 0; using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper)) { try { using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).WithCurrentCulture()) { var actualResultSetCount = 0; do { commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation ? await ConsumeResultSetWithPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture() : await ConsumeResultSetWithoutPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture(); actualResultSetCount++; }while (commandIndex < ResultSetEnds.Count && await reader.NextResultAsync(cancellationToken).WithCurrentCulture()); Contract.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex); #if DEBUG var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e); expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0; Contract.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount); #endif } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Strings.FormatUpdateStoreException(), context, ex, commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].StateEntries : new StateEntry[0]); } } return(commandIndex); }