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