Na quarta parte deste artigo apresentamos como podemos realizar o tratamento da concorrência com foco no Entity Framework fazendo o tratando a concorrência pela versão de linha.
Neste artigo vamos abordar alguns aspectos da concorrência pessimista.
O controle pessimista da concorrência
O controle pessimista da concorrência exige que você faça o bloqueio de registros no banco de dados antes de usá-los. Quando você quer atualizar os dados e não quer correr o risco algum de que outro usuário possa estar acessando o mesmo registro ao mesmo tempo, você faz o bloqueio exclusivo e fisicamente do registro na base de dados.
Dessa forma, nenhum outro usuário poderá acessar os dados bloqueados (seja para leitura ou atualização), dando assim a segurança de que somente você, que iniciou o bloqueio, tem acesso a eles. Qualquer outro usuário somente terá acesso aos dados após a liberação do bloqueio. Essa abordagem é conhecida como concorrência pessimista.
A grande vantagem dessa abordagem é que ela dá acesso exclusivo aos dados ao usuário que os bloqueou. Mas o seu problema é que ela traz efeitos colaterais que afetam o desempenho e a usabilidade da aplicação.
A seguir listamos os principais problemas do controle pessimista da concorrência:
- Ele aumenta a complexidade de sua aplicação visto que você terá que gerenciar os bloqueios;
- Por ter que aumentar os recursos para gerenciar os bloqueios, a memória usada para tratar os registros bloqueados, e a indisponibilidade em usar outros recursos, a aplicação fica mais lenta e usa mais recursos do servidor;
- O desempenho da aplicação é afetado conforme o número de usuários aumenta, pois o número de bloqueios também aumenta;
- O desenvolvedor tem que criar código específico para tratar o acesso ao banco de dados, pois o Entity Framework não suporta a concorrência pessimista de forma nativa;
- Não existe um suporte direto do LINQ to Entities para a concorrência pessimista. Usando o EF 5 você pode usar a tabela UPDLOCK com o método SQLQuery para obter um melhor resultado;
- Podem ocorrer situações de deadlock, o que caracteriza uma situação em que ocorre um impasse e dois ou mais processos ficam impedidos de continuar suas execuções, ou seja, ficam bloqueados indefinidamente.
Diante deste quadro, a abordagem da concorrência pessimista deve ser usada somente quando for realmente necessária, visto que os problemas causados por ela superam seus benefícios.
Geralmente a utilização da abordagem da concorrência otimista resolve a maioria dos problemas dos conflitos e deve ser a indicada para a grande maioria dos casos.
Mesmo assim, se você não tiver outra opção, saiba que mesmo o Entity Framework não suportando a concorrência pessimista diretamente, você ainda tem opções para implementá-la usando código customizado.
A seguir temos as duas técnicas mais comuns para realizar esta tarefa:
- Proporcionar o suporte usando procedimentos armazenados. Você coloca a ação dentro de uma transação e se baseia na utilização de ROWLOCK e HOLDLOCK para executar a tarefa;
- Usando código LINQ To Entities especializado com os métodos SQLQuery() ou ExecuteStoreQuery() e a tabela UPDLOCK para alcançar os resultados desejados. (Esta técnica é extremamente complexa).
Uma outra opção seria a utilização de produtos de terceiros, como o ORM Telerik OpenAccess.
No último artigo da série vamos concluir mostrando uma aplicação da concorrência otimista.