none
Transaction Scope e código legado com SqlTransaction RRS feed

  • Pergunta

  • Estamos desenvolvendo um "wrapper" (. NET 4.0), que irá chamar vários componentes legados c # (. NET 2.0) desenvolvidos usando seus próprios controles de transação. Internamente, esses componentes estão usando SqlTransactions (com BeginTran, Commit e Rollback) explicitamente. Queremos evitar ter que alterar esses componentes.

    Precisamos também chamar alguns métodos desses componentes controlando a transação no nível do wrapper (usando TransactionScope).

    Vocês acham que é possível fazer isso? Ou será que precisamos refatorar o código legado? Será que o SqlTransaction obedecerá o TransactionScope?


    obrigado

    sexta-feira, 24 de agosto de 2012 00:19

Todas as Respostas

  • Olá Felipe,

    Sim, o SqlTransaction vai obeceder o Transaction Scope.

    Estouy trabalhando em um projeto onde utilizo os dois em conjunto e tudo tem funcionado bem.

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    Microsoft MVP - Data Platform Development
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    sexta-feira, 24 de agosto de 2012 11:54
    Moderador
  • Fernando,

    Obrigado pelo retorno.

    Em uma "prova de conceito" que estamos fazendo, percebemos que quando simulamos um "rollback", a seguinte exceção é gerada:

    "The transaction under which this method call was executing was asynchronously aborted."

    Ela é gerada no momento em que o "TransactionScope" termina a sua execução (saída do using). Uma exeção interna também é gerada, dizendo que "No Corresponding BEGIN TRANSACTION error When ROLLBACK TRANSACTION".

    O código usado na POC é o seguinte:

     static void Main(string[] args)
            {
                try
                {
                    using (TransactionScope txScope = new TransactionScope(TransactionScopeOption.Required))
                    {
                        bool ret = ExecuteQuery();

                        txScope.Complete();

                        Console.WriteLine("transação executada com sucesso = ");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("transação falhou!");
                }
                
                Console.ReadKey();
            }


    public static bool ExecuteQuery()
            {
                string strSQL = string.Empty;
                string strConn = string.Empty;

                string sqlQuery = "UPDATE statement...";

                SqlTransaction tran = null;

                try
                {
                    strConn = @"xxxx; Database=TesteTransacaoServicos; Integrated Security=true";

                    SqlCommand sqlCMD = new SqlCommand();
                    SqlConnection con = new SqlConnection(strConn);

                    con.Open();

                    tran = con.BeginTransaction();

                    sqlCMD.Connection = con;
                    sqlCMD.Transaction = tran;
                    sqlCMD.CommandText = sqlQuery;
                    sqlCMD.CommandType = CommandType.Text;
                    sqlCMD.ExecuteNonQuery();

                    tran.Commit();
                    
                    con.Close();
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    throw ex;
                }

                return true;
            }
    sexta-feira, 24 de agosto de 2012 15:05
  • Olá Felipe,

    No casso isso parece ser um comportamento por design.

    No caso, vc esta utilizando um comando UPDATE válido não?

    Erros de sintaxe não entram nos blocos de transação.

    Veja este link: http://support.microsoft.com/kb/309335

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    Microsoft MVP - Data Platform Development
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    sábado, 25 de agosto de 2012 12:45
    Moderador
  • Felipe,

    quantas Threads vocês estão abrindo para simular em paralelo esse problema? Fizemos alguns testes com o nível de ISOLAMENTO Snapshot e tivemos esse mesmo problema seu de dar rollback em uma transação não correspondente.

    O que aconteceu foi que em poucos casos, a transação sofria deadlock e a thread fazia o rollback "atrasado", ocasionando o erro.

    segunda-feira, 10 de setembro de 2012 22:55