Entity Framework - Tratando o problema da concorrência na alteração dos dados - II


Na primeira parte deste artigo apresentamos o tratamento da concorrência com foco no Entity Framework onde vimos o comportamento padrão oferecido pelo EF e como ele funciona.

Vamos continuar mostrando como implementar o tratamento da concorrência onde iremos adicionar código à nossa aplicação de forma a mitigar alguns dos problemas da concorrência.

O tratamento da concorrência para alterações de dados

Existem situações onde o desenvolvedor tem que atuar de forma a realizar o tratamento da concorrência para contornar possíveis conflitos que ocorrem no acesso simultâneo dos dados para operações que modificam os registros do banco de dados. Veremos a seguir uma forma de fazer isso.

Vamos continuar usando o nosso exemplo criado no artigo anterior. Abra o projeto EF_TestandoConcorrencia no VS 2012 Express for desktop.

Selecione o formulário AtualizaRegistro e inclua um novo botão de comando a partir da ToolBox com o texto - Concorrência a nível de Campo - e name = btnConcorrenciaCampo;

A seguir inclua o código a seguir no evento Click deste botão de comando:

  private void btnConcorrenciaCampo_Click(object sender, EventArgs e)
   {
            // cria o contexto
            ConcorrenciaContainer context = new ConcorrenciaContainer();
            // Obtem os registros de compras
            var _DataCompra = from DC in context.Compras select DC;

            // Realiza as atualizações
            if (NomeAnterior != txtNomeCliente.Text)
            {
                if (_DataCompra.First().Cliente.nome != NomeAnterior)
                {
                    if (MessageBox.Show("O o valor do campo foi alterado para " + _DataCompra.First().Cliente.nome + " Deseja alterar de qualquer forma ?", "Atualizando dados mais recentes", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        context.Compras.First().Cliente.nome = txtNomeCliente.Text;
                }
                else
                {
                    context.Compras.First().Cliente.nome = txtNomeCliente.Text;
                }
            }

            if (DataCompraAnterior.ToShortDateString() != txtDataCompra.Text)
            {
                if (!_DataCompra.First().DataCompra.Equals(DataCompraAnterior))
                {
                    if (MessageBox.Show("O valor do campo DataCompra foi alterado para " + _DataCompra.First().DataCompra + " Deseja alterar de qualquer forma ?", "Atualizando dado mais recente", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        context.Compras.First().DataCompra = Convert.ToDateTime(txtDataCompra.Text);
                }
                else
                {
                    context.Compras.First().DataCompra = Convert.ToDateTime(txtDataCompra.Text);
                }
            }

            if (QuantidadeAnterior.ToString() != txtQuantidade.Text)
            {
                if (!_DataCompra.First().Quantidade.Equals(QuantidadeAnterior))
                {
                    if (MessageBox.Show("O valor do campo Quantidade foi alterado para " + _DataCompra.First().Quantidade + " Alterar mesmo assim ?", "Atualizado dados mais recentes", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        context.Compras.First().Quantidade = Convert.ToDecimal(txtQuantidade.Text);
                }
                else
                {
                    context.Compras.First().Quantidade = Convert.ToDecimal(txtQuantidade.Text);
                }
            }

            context.SaveChanges();
            // exibe os dados
            ExibirDados();
       }

Observe que o código agora verifica os valores dos dados anteriores contra o banco de dados antes de realizar uma atualização. Note que não precisamos alterar o modelo somente incluir código em nosso projeto.

O código incluindo verifica quando os dados anteriores não conferirem com os dados atuais do banco de dados e solicita uma confirmação ao usuário para realizar a atualização; somente com a confirmação do usuário os dados serão atualizados.

Vamos ver então como funciona :

Execute o projeto e clique no botão - Testando a Concorrência. Teremos as duas instâncias do formulário AtualizaRegistro conforme mostra a figura a seguir:

1- Selecione o formulário para o Usuario A e altere a quantidade de 2.99 para 3.99. Clique no botão - Concorrência a nível de Campo:

Você verá uma caixa de diálogo contendo o valor atual do banco de dados. Note que o valor da  quantidade agora é 3.99 o que confere com o valor atualizado pelo Usuario A.

2- Clique no botão OK para fechar a caixa de mensagem;

3- Selecione o formulário para o Usuario B e altere o campo Quantidade para 9.99. Clique no botão  Concorrência a nível de Campo:;

Você verá uma caixa de mensagem informando que o campo foi alterado para 3.99 e solicitando a confirmação para alterar para o novo valor 9.99:

A mensagem foi exibida porque o valor do campo no banco de dados (3.99) não confere com o valor informado no formulário (9.99).

Clicando no botão Sim teremos a caixa de mensagem exibindo o novo valor atualizado para o campo:

3- Selecione o formulário para o Usuario A e altere a quantidade de 9.99 para 8.99. Clique no botão - Concorrência a nível de Campo:

Você verá uma caixa de diálogo informando que o valor do campo já havia sido alterado para 9.99 e solicitando sua confirmação para alterar para o novo valor:

 

Clique no botão Não;

 

Você verá a caixa de mensagem exibindo o valor atual do campo quantidade (9.99) no banco de dados e não o valor informado no formulário (8.99)  pois a atualização não foi confirmada:

 

 

Dessa forma vimos como podemos incluir código para tratar a concorrência a nível de campo contornando assim conflitos em determinadas situações.

 

Na continuação irei abordar a concorrência a nível de campo com o Entity Framework.

Joã 3:26 E foram ter com João e disseram-lhe: Rabi, aquele que estava contigo além do Jordão, do qual tens dado testemunho, eis que está batizando, e todos vão ter com ele.

Joã 3:27 Respondeu João: O homem não pode receber coisa alguma, se não lhe for dada do céu.

Joã 3:28 Vós mesmos me sois testemunhas de que eu disse: Não sou o Cristo, mas sou enviado adiante dele.

Referências:


José Carlos Macoratti