Transactionscope - Rollback problem

Asked

Viewed 468 times

2

I need the Transactionscope do Rollback case any of these foreach error.

I added a Exception manually between 2º and 3º foreach to test whether the rollback, but the information saved in the bank of the 1st and 2nd foreach were not undone.

Someone would tell me if this implementation is correct, and why the rollback is not done?

OBS.: SQL Server Database.

I have the following method:

public static void LancarFinanceiroPedido(List<Contas_Receber> lstContasReceber, List<Recebimentos_Contas_Receber> lstRecebimentos, List<Movimento_Conta> lstMovimentosConta, List<Caixa> lstLancamentosCaixa)
        {
          using (var ts = new TransactionScope(TransactionScopeOption.RequiresNew,  new TransactionOptions()
          {
              IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted,
              Timeout = SETCOM_BaseDados.DBTimeout
          })){
                foreach (var item in lstContasReceber)
                    DAO<Contas_Receber>.Create(item);

                foreach (var item in lstRecebimentos)
                    DAO<Recebimentos_Contas_Receber>.Create(item);

                throw new Exception("Exceção proposital para testar o TransactionScope!");

                foreach (var item in lstMovimentosConta)
                    DAO<Movimento_Conta>.Create(item);

                foreach (var item in lstLancamentosCaixa)
                    DAO<Caixa>.Create(item);

                ts.Complete();
            }
        }

And a CRUD created this way:

public static class DAO<T> where T : class
    {
        public static void Create(T entidade)
        {
            using (var db = new SETCOM_BaseDados())
            {
                db.Set<T>().Add(entidade);
                db.SaveChanges();
            }
        }

        public static void Update(T entidade)
        {
            using (var db = new SETCOM_BaseDados())
            {
                ((IObjectContextAdapter)db).ObjectContext.ObjectStateManager.ChangeObjectState(entidade, System.Data.Entity.EntityState.Modified);
                db.SaveChanges();
            }
        }

        public static void Delete(T entidade)
        {
            using (var db = new SETCOM_BaseDados())
            {
                db.Set<T>().Remove(entidade);
                db.SaveChanges();
            }
        }

        public static T Find(object chave)
        {
            using (var db = new SETCOM_BaseDados())
            {
                return db.Set<T>().Find(chave);
            }
        }

        public static List<T> FindAll()
        {
            using (var db = new SETCOM_BaseDados())
            {
                return db.Set<T>().ToList();
            }
        }
    }
  • Which database you are using?

  • I added to the question @Gabrielheming

1 answer

1


I found the problem! Now Rollback is working.

It has everything to do with TransactionScopeOption.RequiresNew vs Transactionscopeoption.Required.

Look at the solution:

My 1st Transactionscope continued the same, but with the parameter Requiresnew.

using (var ts = new TransactionScope(**TransactionScopeOption.RequiresNew**))
    {
        foreach (var item in lstContasReceber)
            DAO<Contas_Receber>.Create(item);

        foreach (var item in lstRecebimentos)
            DAO<Recebimentos_Contas_Receber>.Create(item);

        throw new Exception("Exceção proposital para testar o TransactionScope!");

        foreach (var item in lstMovimentosConta)
            DAO<Movimento_Conta>.Create(item);

        foreach (var item in lstLancamentosCaixa)
            DAO<Caixa>.Create(item);

        ts.Complete();
    }

And in my CRUD was just missing a new one Transactionscope with the parameter Transactionscopeoption.Required, for only then will he understand that the conclusion of this Transactionscope internal, it is vital for the first to be completed.

public static class DAO<T> where T : class
{
    public static void Create(T entidade)
    {
        using (var ts = new TransactionScope(TransactionScopeOption.Required))
        {
            using (var db = new SETCOM_BaseDados())
            {

                db.Set<T>().Add(entidade);
                db.SaveChanges();
            }

            ts.Complete();
        }
    }
} ...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.