Error in TransactionScope

2

I'm trying to make a TransactionScope but it always gives me an error:

  

Application Server Error '/'.

     

A second operation started on this context before a previous   asynchronous operation completed. Use 'await' to ensure that any   asynchronous operations have completed before calling another method   on this context. Any instance members are not guaranteed to be thread   safe.

     

Description: An unhandled exception occurred during the execution of the   current Web request. Examine the stack trace for   more information about the error and where it originated in the code.

     

Exception Details: System.NotSupportedException: A second operation   started on this context before a previous asynchronous operation   completed. Use 'await' to ensure that any asynchronous operations have   completed before calling another method on this context. Any instance   members are not guaranteed to be thread safe.

     

Source Error:

     

Line 150: {Line 151: Client Client =   await db.Clients.SingleAsync (x => x.ClientId == id); Line 152:
  Title title = await db.Titulos.Where (t => t.TituloId ==   client.Title.Imit) .FirstOrDefaultAsync (); Line 153:
  db.Titulos.Remove (title); Line 154: await   db.SaveChangesAsync ();

My code in controller where I do it, is as follows:

[HttpPost, ActionName("Excluir")]
public async Task<ActionResult> ConfirmarExclusao(Guid id)
{
    using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
    {
        Cliente cliente = await db.Clientes.SingleAsync(x => x.ClienteId == id);
        Titulo titulo = await db.Titulos.Where(t => t.TituloId == cliente.Titulo.TituloId).FirstOrDefaultAsync();
        db.Titulos.Remove(titulo);
        await db.SaveChangesAsync();

        db.Clientes.Remove(cliente);
        await db.SaveChangesAsync();
        scope.Complete();
        return RedirectToAction("Indice");
    }
}

Other than the code above, I tried to use ConfigureAwait(); in lines:

Cliente cliente = await db.Clientes.SingleAsync(x => x.ClienteId == id).ConfigureAwait(false);
Titulo titulo = await db.Titulos.Where(t => t.TituloId == cliente.Titulo.TituloId).FirstOrDefaultAsync().ConfigureAwait(false);

But it did not work.

What causes this error?

What do I do to correct it?

Is this the best way to solve this problem?

    
asked by anonymous 08.05.2017 / 06:04

1 answer

2
  

What causes this error?

Notice that here you use as a parameter an aggregate class that has not yet been loaded ( cliente.Titulo ):

Titulo titulo = await db.Titulos.Where(t => t.TituloId == cliente.Titulo.TituloId).FirstOrDefaultAsync();

That is, when you are running this part, the Entity Framework is going to the database to get Titulo for lazy load, which is exactly what you are selecting. Note that at this point in the code cliente.Titulo is not yet loaded.

  

What do I do to correct?

Speed the load on the top line and do not use the bottom line to load:

        using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
        {
            var cliente = await db.Clientes
                                 .Include(c => c.Titulo)
                                 .FirstOrDefaultAsync(c => c.ClienteId == id);//.ConfigureAwait(false);

            // Este não precisa mais.
            // db.Titulos.Remove(titulo);
            // await db.SaveChangesAsync();

            db.Clientes.Remove(cliente);
            await db.SaveChangesAsync();

            scope.Complete();
            return RedirectToAction("Indice");
        }
  

Is this the best way to solve this problem?

Yes, you are asking the Entity Framework to look at Cliente and its Titulo before deleting them.

    
08.05.2017 / 06:32