CRM 2015 – Controle de Transações (ExecuteTransactionRequest)

Pessoal,

Uma nova feacture disponibilizada no Update 1 do CRM 2015 é a possibilidade do controle de transações para processos em backgroup (batching), que é concebida pela classe “ExecuteTransactionRequest“.

IC472447

A classe “ExecuteTransactionRequest” é muito semelhante a “ExecuteMultipleRequest“, porém temos como garantia o conceito de transação, deste modo, qualquer erro retornado durante o acesso via SDK fará com que todos os demais registros que já foram inseridos no banco de dados sejam retrocedidos (rollback), aliás, na prática os registros anteriores foram adicionados, mas não foram “commitados”, só serão quando a totalidade de registros for inserida com sucesso.

Bom, mas para qual propósito devemos utilizar o “ExecuteTransaction”?

O conceito transação também traz consigo a ideia de Atomicidade, ou seja, existem cenários que desejamos que todos registros sejam carregados ou nenhum caso exista ao menos um problema. Um bom exemplo pode ser dado no caso de uma integração de dados diária, cujo dados são informados por outro sistema, que realiza uma carga de Clientes (accounts), onde desejamos que sejam importados todos os novos clientes, a única validação feita é a existência de um valor no atributo “CNPJ” (A regra de validação foi criada em um plugin da entidade Account). Caso algum cliente não possua seu CNPJ informado, precisamos que todos os demais desta mesma integração, que já foram inseridos sejam removidos do CRM

A diferença básica quando comparamos com o ExecuteMultiple, é que o ExecuteMultiple não controla transação, temos a propriedade “ContinueOnError” que pode ou não continuar as execuções mesmo após um erro, porém, os registros anteriormente inseridos não serão removidos, pois já foram “commitados” no banco de dados do CRM.

Em relação a performance fiz alguns testes com 100, 500 e 1000 registros em comparação com o ExecuteMultiple e os tempos são muito similares, não existe ganho ou perda de desempenho.

Abaixo criei um exemplo prático

public void ExecuteTransaction()
{
    int cont = 100;
    DateTime inicio = DateTime.Now;

    Console.WriteLine();
    Console.WriteLine("EXECUTETRANSACTION " + cont + " Data Início: " + inicio);

    try
    {
        CreateRequest createRequest;

        // Create an ExecuteTransactionRequest object.
        ExecuteTransactionRequest transactions = new ExecuteTransactionRequest()
        {
            ReturnResponses = true, // Para retornar os objetos Response
            // Create an empty organization request collection.
            Requests = new OrganizationRequestCollection()
        };

        // Percorre o contador adicionando CreateRequests da entidade Account
        for (int i = 0; i < cont; i++)
        {
            // Cria o objeto Entity com uma nova Account
            Entity account = new Entity("account");
            account.Attributes.Add("name", "EXECUTETRANSACTION_" + i + " " + DateTime.Now);

            createRequest = new CreateRequest { Target = account };
            transactions.Requests.Add(createRequest);

            // Desabilitar para simular um erro no CRM
            //if (i == 4)
            //{
            //    // Cria o objeto Entity com uma nova Account
            //    Entity account1 = new Entity("account");
            //    account1.Attributes.Add("fax", "123456789012345678901234567890123456789012345678901234567890"); // Atributo fax com mais de 50 caracteres, irá provovar um erro

            //    createRequest = new CreateRequest { Target = account1 };
            //    transactions.Requests.Add(createRequest);
            //}
        }

        // Executa as Transações
        ExecuteTransactionResponse responseWithResults = (ExecuteTransactionResponse)service.Execute(transactions);
    }
    catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
    {
        ExecuteTransactionFault fault = (ExecuteTransactionFault)ex.Detail;

        int faultedIndex = fault.FaultedRequestIndex; // Caso ocorra algum erro podemos verificar qual registro teve o problema través do "FaultedRequestIndex"
    }

    DateTime fim = DateTime.Now;

    Console.WriteLine();
    Console.WriteLine("EXECUTETRANSACTION " + cont + " Data Início: " + inicio + " Data Fim: " + fim);
}

Alguns pontos a considerar:

  • Temos as mesmas restrições da classe ExecuteMultipleRequest em relação a quantidade de objetos (requests) e limites de execuções simultâneas
  • Não existem restrições para tipos diferentes de objetos de request (Create, Update, Delete e etc), porém não podemos ter outros ExecuteTransaction ou ExecuteMultiple
  • Devido ao uso de um único bloco transacional os registros que ainda não foram “commitados” ficam bloqueados, por tanto não generalize e pense bem antes de implementar

[]’s,

Tiago Cardoso

Anúncios

Sobre Tiago Michelini Cardoso

I have been working with IT since 2006, almost of this time using Microsoft Dynamics CRM/365 as a source of solutions. I graduated in Bachelor of Information Systems at FIAP (Brazil) in 2012. I really love what I do! Technology has been my interest since always. Even in a tool different world of the current. When we didn't have internet, tablets, smartphones e social networks! Although I have worked in some roles, I can't give up "the developer life". Even so far of the greatest developers. Development in general is the thing that I love to work! I started my contributions about Dynamics in 2010. At the beginning, I used to help at MSDN and TechNet forums. But now, I'm dedicating all my time in my personal blog! Currently, I have the enormous honour of being the only Brazilian who got the award for Microsoft MVP (Most Valuable Professional) for Microsoft Dynamics CRM/365 product. I have been receiving the award since 2012.
Esse post foi publicado em Dynamics CRM e marcado , . Guardar link permanente.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s