Descrever a concorrência
Uma característica central dos bancos de dados multiusuário é a simultaneidade. A concorrência utiliza bloqueio e contenção para permitir que os dados permaneçam consistentes com muitos utilizadores a atualizar e a ler dados ao mesmo tempo. Por exemplo, por causa dos custos de envio, todos os nossos produtos têm um aumento de preço de US $ 5. Ao mesmo tempo, devido às taxas de câmbio, todos os produtos sofreram uma redução de preço de 3%. Se essas atualizações acontecerem exatamente ao mesmo tempo, o preço final será variável e é provável que haja muitos erros. Usando o bloqueio, você pode garantir que uma atualização será concluída antes que a outra comece.
A simultaneidade ocorre no nível da transação. Uma transação de gravação pode impedir que outras transações atualizem e até leiam os mesmos dados. Da mesma forma, uma transação de leitura pode bloquear outros leitores ou até mesmo alguns escritores. Por esse motivo, é importante evitar transações desnecessariamente longas ou transações que abranjam quantidades excessivas de dados.
Há muitos níveis específicos de isolamento de transação que podem ser usados para definir como um sistema de banco de dados lida com vários usuários. Para os fins deste módulo, examinaremos amplas categorias de nível de isolamento, bloqueio otimista e bloqueio pessimista.
Observação
O detalhe completo do bloqueio de transação além da simultaneidade está relacionado mais ao desempenho e não depende apenas do código - embora um bom código tenha um desempenho melhor. Consulte o Guia Detalhado de Bloqueio de Transações e Versão de Linhas do SQL Server para obter mais detalhes. Para obter informações sobre bloqueio, consulte também a documentação de Desempenho do SQL Server.
Concorrência otimista
Com o bloqueio otimista, há uma suposição de que poucas atualizações conflitantes ocorrerão. No início da transação, o estado inicial dos dados é registrado. Antes da transação ser confirmada, o estado atual é comparado com o estado inicial. Se os estados forem os mesmos, a transação é concluída. Se os estados forem diferentes, a transação é revertida.
Por exemplo, você tem uma tabela contendo ordens de venda dos últimos anos. Esses dados são atualizados com pouca frequência, mas os relatórios são executados com frequência. Ao usar o bloqueio otimista, as transações não bloqueiam umas às outras e o sistema funciona de forma mais eficiente. Infelizmente, foram encontrados erros nos dados dos últimos anos e atualizações precisam ocorrer. Enquanto uma transação está atualizando cada linha, outra transação faz uma pequena edição em uma única linha ao mesmo tempo. Como o estado dos dados foi alterado enquanto a transação inicial estava em execução, toda a transação é revertida.
Controle de concorrência pessimista
Com o bloqueio pessimista, há uma suposição de que muitas atualizações estão acontecendo com os dados ao mesmo tempo. Ao usar bloqueios, apenas uma atualização pode acontecer ao mesmo tempo, e as leituras dos dados são impedidas enquanto as atualizações estão ocorrendo. Isso pode evitar grandes reversões, como visto no exemplo anterior, mas pode fazer com que as consultas sejam bloqueadas desnecessariamente.
É importante considerar a natureza dos seus dados e as consultas em execução nos dados ao decidir se deseja usar simultaneidade otimista ou pessimista para garantir o melhor desempenho.
Isolamento de snapshot
Há cinco níveis de isolamento diferentes no SQL Server, mas para este módulo vamos nos concentrar em apenas READ_COMMITTED_SNAPSHOT_OFF e READ_COMMITTED_SNAPSHOT_ON. READ_COMMITTED_SNAPSHOT_OFF é o nível de isolamento padrão para o SQL Server. READ_COMMITTED_SNAPSHOT_ON é o nível de isolamento padrão para o Banco de Dados SQL do Azure.
READ_COMMITTED_SNAPSHOT_OFF manterá bloqueios nas linhas afetadas até ao final da transação, caso a consulta esteja a usar o nível de isolamento 'read committed'. Embora seja possível que algumas atualizações ocorram, como a criação de uma nova linha, isso impedirá que a maioria das alterações conflitantes nos dados sejam lidas ou atualizadas. Trata-se de uma concorrência pessimista.
READ_COMMITTED_SNAPSHOT_ON tira um instantâneo dos dados. As atualizações são efetuadas nesta captura de dados, permitindo que outras conexões consultem os dados originais. No final da transação, o estado atual dos dados é comparado com o instantâneo. Se os dados forem os mesmos, a transação é confirmada. Se os dados forem diferentes, a transação será revertida.
Para alterar o nível de isolamento para READ_COMMITTED_SNAPSHOT_ON, execute o seguinte comando:
ALTER DATABASE *db_name* SET READ_COMMITTED_SNAPSHOT ON;
Para alterar o nível de isolamento para READ_COMMITTED_SNAPSHOT_OFF, execute o seguinte comando:
ALTER DATABASE *db_name* SET READ_COMMITTED_SNAPSHOT OFF;
Se o banco de dados tiver sido alterado para ativar o instantâneo de leitura confirmada, qualquer transação que use o nível de isolamento de leitura confirmada padrão usará o bloqueio otimista.
Observação
O isolamento de instantâneo ocorre apenas para transações com leitura confirmada. As transações que usam outros níveis de isolamento não são afetadas.