TransactionScope - Problem with Rollback

1

I need the TransactionScope to rollback if any of these foreach returns error.

I added an Exception manually between 2nd and 3rd foreach to test if rollback was working, but the information saved in the 1st and 2 foreach were not undone.

Can anyone tell me if this implementation is correct, and why rollback is not done?

Note: SQL Server Bank .

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();
            }
        }
    }
    
asked by anonymous 23.10.2017 / 21:02

1 answer

1

I found the problem! Rollback is now working.

It is all about TransactionScopeOption.RequiresNew vs TransactionScopeOption.Required .

See how the solution was:

My 1st TransactionScope continued the same, but with the RequiresNew parameter.

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 I was just missing a new TransactionScope with the TransactionScopeOption.Required parameter, since only then will he understand that the completion of this TransactionScope > internal, it is vital for the 1st 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();
        }
    }
} ...
    
24.10.2017 / 14:10