Transações e controlo de simultaneidade otimista
APLICA-SE A: NoSQL
As transações de bases de dados fornecem um modelo de programação seguro e previsível para lidar com alterações simultâneas aos dados. As bases de dados relacionais tradicionais, como SQL Server, permitem-lhe escrever a lógica de negócio através de procedimentos armazenados e/ou acionadores, enviam-na para o servidor para execução diretamente no motor de base de dados. Com as bases de dados relacionais tradicionais, tem de lidar com duas linguagens de programação diferentes da linguagem de programação de aplicações (não transacionais), como JavaScript, Python, C#, Java, etc. e a linguagem de programação transacional (por exemplo, T-SQL) que é executada nativamente pela base de dados.
O motor de base de dados no Azure Cosmos DB suporta transações completas compatíveis com ACID (Atomicidade, Consistência, Isolamento, Durabilidade) com isolamento de instantâneos. Todas as operações da base de dados no âmbito da partição lógica de um contentor são executadas de forma transacional no motor de base de dados que é alojado pela réplica da partição. Estas operações incluem operações de escrita (atualização de um ou mais itens na partição lógica) e operações de leitura. A tabela seguinte ilustra diferentes operações e tipos de transação:
Operação | Tipo de Operação | Transação de Item Único ou Múltiplo |
---|---|---|
Inserir (sem um acionador pré/post) | Escrita | Transação de item único |
Inserir (com um acionador pré/post) | Escrever e Ler | Transação de vários itens |
Substituir (sem um acionador pré/post) | Escrita | Transação de item único |
Substituir (por um acionador pré/post) | Escrever e Ler | Transação de vários itens |
Upsert (sem um acionador pré/post) | Escrita | Transação de item único |
Upsert (com um acionador pré/post) | Escrever e Ler | Transação de vários itens |
Eliminar (sem um acionador pré/post) | Escrita | Transação de item único |
Eliminar (com um acionador pré/post) | Escrever e Ler | Transação de vários itens |
Executar procedimento armazenado | Escrever e Ler | Transação de vários itens |
Execução iniciada pelo sistema de um procedimento de intercalação | Escrita | Transação de vários itens |
Execução iniciada pelo sistema de eliminação de itens com base na expiração (TTL) de um item | Escrita | Transação de vários itens |
Leitura | Leitura | Transação de item único |
Feed de Alterações | Leitura | Transação de vários itens |
Leitura Paginada | Leitura | Transação de vários itens |
Consulta Paginada | Leitura | Transação de vários itens |
Executar o UDF como parte da consulta paginada | Leitura | Transação de vários itens |
Transações de vários itens
O Azure Cosmos DB permite-lhe escrever procedimentos armazenados, acionadores pré/post, funções definidas pelo utilizador (UDFs) e procedimentos de intercalação no JavaScript. O Azure Cosmos DB suporta nativamente a execução de JavaScript dentro do motor de base de dados. Pode registar procedimentos armazenados, acionadores pré/post, funções definidas pelo utilizador (UDFs) e intercalar procedimentos num contentor e, posteriormente, executá-los de forma transacional no motor de base de dados do Azure Cosmos DB. Escrever lógica de aplicação em JavaScript permite uma expressão natural do fluxo de controlo, âmbito de variáveis, atribuição e integração de primitivos de processamento de exceções nas transações de base de dados diretamente na linguagem JavaScript.
Os procedimentos armazenados, acionadores, UDFs e procedimentos de intercalação baseados em JavaScript são encapsulados numa transação ACID ambiente com isolamento de instantâneo em todos os itens dentro da partição lógica. Durante a sua execução, se o programa JavaScript emitir uma exceção, toda a transação é abortada e revertida. O modelo de programação resultante é simples, mas poderoso. Os programadores de JavaScript obtêm um modelo de programação durável enquanto ainda utilizam as construções de linguagem familiares e os primitivos da biblioteca.
A capacidade de executar o JavaScript diretamente no motor de base de dados fornece desempenho e execução transacional de operações de base de dados em relação aos itens de um contentor. Além disso, uma vez que o motor de base de dados do Azure Cosmos DB suporta nativamente JSON e JavaScript, não existem erros de correspondência entre os sistemas de tipo de uma aplicação e a base de dados.
Controlo da simultaneidade otimista
O controlo de simultaneidade otimista permite-lhe evitar atualizações e eliminações perdidas. As operações simultâneas em conflito estão sujeitas ao bloqueio pessimista regular do motor de base de dados alojado pela partição lógica proprietária do item. Quando duas operações simultâneas tentam atualizar a versão mais recente de um item numa partição lógica, uma delas ganha e a outra falha. No entanto, se uma ou duas operações que tentam atualizar em simultâneo o mesmo item tinham lido anteriormente um valor mais antigo do item, a base de dados não sabe se o valor lido anteriormente por ou ambas as operações em conflito era, de facto, o valor mais recente do item. Felizmente, esta situação pode ser detetada com o Controlo de Simultaneidade Otimista (OCC) antes de permitir que as duas operações introduzam o limite de transação dentro do motor de base de dados. O OCC protege os seus dados de substituir acidentalmente as alterações efetuadas por outras pessoas. Também impede que outras pessoas substituam acidentalmente as suas próprias alterações.
Implementar o controlo de simultaneidade otimista com cabeçalhos ETag e HTTP
Cada item armazenado num contentor do Azure Cosmos DB tem uma propriedade definida pelo _etag
sistema. O valor do _etag
é gerado e atualizado automaticamente pelo servidor sempre que o item é atualizado. _etag
pode ser utilizado com o cabeçalho de pedido fornecido pelo if-match
cliente para permitir que o servidor decida se um item pode ser atualizado condicionalmente. O valor do if-match
cabeçalho corresponde ao valor de _etag
no servidor, o item é atualizado. Se o valor do cabeçalho do if-match
pedido já não estiver atualizado, o servidor rejeita a operação com uma mensagem de resposta "Falha de pré-condição HTTP 412". Em seguida, o cliente pode obter novamente o item para adquirir a versão atual do item no servidor ou substituir a versão do item no servidor com o seu próprio _etag
valor para o item. Além disso, _etag
pode ser utilizado com o if-none-match
cabeçalho para determinar se é necessária uma nova correspondência de um recurso.
O valor do _etag
item é alterado sempre que o item é atualizado. Para operações de substituição de itens, if-match
tem de ser expressa explicitamente como parte das opções de pedido. Por exemplo, veja o código de exemplo no GitHub. _etag
os valores são verificados implicitamente para todos os itens escritos tocados pelo procedimento armazenado. Se for detetado algum conflito, o procedimento armazenado reverterá a transação e gerará uma exceção. Com este método, todas ou nenhuma escrita no procedimento armazenado é aplicada atomicamente. Este é um sinal para a aplicação para reaplicar atualizações e repetir o pedido de cliente original.
Controlo de simultaneidade otimista e distribuição global
As atualizações simultâneas de um item estão sujeitas ao OCC pela camada de protocolo de comunicação do Azure Cosmos DB. Para contas do Azure Cosmos DB configuradas para escritas de região única, o Azure Cosmos DB garante que a versão do lado do cliente do item que está a atualizar (ou a eliminar) é a mesma que a versão do item no contentor do Azure Cosmos DB. Isto garante que as suas escritas estão protegidas contra serem substituídas acidentalmente pelas escritas de outras pessoas e vice-versa. Num ambiente multiutilizador, o controlo de simultaneidade otimista protege-o de eliminar ou atualizar acidentalmente a versão errada de um item. Como tal, os itens são protegidos contra os infames problemas de "atualização perdida" ou "eliminação perdida".
Numa conta do Azure Cosmos DB configurada com escritas em várias regiões, os dados podem ser consolidados de forma independente em regiões secundárias se _etag
corresponderem aos dados na região local. Assim que os novos dados forem consolidados localmente numa região secundária, serão intercalados no hub ou na região primária. Se a política de resolução de conflitos intercalar os novos dados na região do hub, estes dados serão replicados globalmente com o novo _etag
. Se a política de resolução de conflitos rejeitar os novos dados, a região secundária será revertida para os dados originais e _etag
.
Passos seguintes
Saiba mais sobre as transações de bases de dados e o controlo de simultaneidade otimista nos seguintes artigos: