Back-End

24 jun, 2014

Entity Framework – Tratando o problema da concorrência na alteração dos dados – Parte 02

Publicidade

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 incluído verifica quando os dados anteriores não conferem 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:

ef_tpc21

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.

ef_tpc22

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 de 9.99:

ef_tpc24

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:

ef_tpc25

4. Selecione o formulário para o Usuário 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:

ef_tpc26

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:

ef_tpc27

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.