Partilhar via


Transações e controle de simultaneidade otimista

As transações na base de dados fornecem um modelo de programação seguro e previsível para lidar com alterações simultâneas nos dados. Bases de dados relacionais tradicionais, como o SQL Server, permitem-lhe escrever a lógica de negócio usando procedimentos armazenados e triggers, e depois enviá-la para o servidor para execução diretamente no motor da base de dados.

Com bases de dados relacionais tradicionais, é necessário lidar com duas linguagens de programação diferentes: uma linguagem de programação de aplicações não transacional, como JavaScript, Python, C# ou Java; e uma linguagem de programação transacional, como o T-SQL, que é executada nativamente pela base de dados.

O motor de base de dados no Azure Cosmos DB suporta transações totalmente compatíveis com ACID (atomicidade, consistência, isolamento, durabilidade) com isolamento instantâneo. Todas as operações na base de dados dentro do âmbito da partição lógica de um contentor são executadas transacionalmente dentro do motor de base de dados alojado pela réplica da partição. Estas operações incluem tanto operações de escrita (atualização de um ou mais itens dentro da partição lógica) como de leitura.

A tabela seguinte lista diferentes operações e tipos de transações:

Operation Tipo de operação Transação de item único ou múltiplo
Insira (sem gatilho pré/pós) Escreve Transação de item único
Inserção (com gatilho pré/pós) Escreva e leia Transação de múltiplos itens
Substituir (sem gatilho pré/pós-gatilho) Escreve Transação de item único
Substituir (com um gatilho pré/pós) Escreva e leia Transação de múltiplos itens
Upsert (sem pré/pós-gatilho) Escreve Transação de item único
Upsert (com pré/pós-gatilho) Escreva e leia Transação de múltiplos itens
Apagar (sem um gatilho pré ou pós-ativação) Escreve Transação de item único
Apagar (com um gatilho antes/depois) Escreva e leia Transação de múltiplos itens
Executar procedimento armazenado Escreva e leia Transação de múltiplos itens
Execução iniciada pelo sistema de um procedimento de fusão Escreve Transação de múltiplos itens
Execução iniciada pelo sistema para eliminar itens com base na expiração (TTL) de um item Escreve Transação de múltiplos itens
Leitura Leitura Transação de item único
Feed de alterações Leitura Transação de múltiplos itens
Leitura paginada Leitura Transação de múltiplos itens
Consulta paginada Leitura Transação de múltiplos itens
Executar UDF como parte da consulta paginada Leitura Transação de múltiplos itens

Transações com múltiplos itens

O Azure Cosmos DB permite-lhe escrever procedimentos armazenados, triggers, funções definidas pelo utilizador e procedimentos de fusão em JavaScript. O Azure Cosmos DB suporta nativamente a execução de JavaScript dentro do seu motor de base de dados. Pode registar procedimentos armazenados, triggers de pré/pós-execução, funções definidas pelo utilizador (UDFs) e procedimentos de mesclagem num contêiner, para depois executá-los transacionalmente dentro do motor de base de dados do Azure Cosmos DB. Escrever lógica de aplicação em JavaScript permite a expressão natural do fluxo de controlo, alcance de variáveis, atribuição e integração de primitivas de gestão de exceções dentro das transações da base de dados diretamente na linguagem JavaScript.

Os procedimentos armazenados, triggers, UDFs e procedimentos de fusão baseados em JavaScript estão envolvidos numa transação ACID ambiente com isolamento instantâneo em todos os itens dentro da partição lógica. Durante a sua execução, se o programa JavaScript lançar uma exceção, toda a transação é abortada e revertida. O modelo de programação resultante é simples, mas poderoso. Os programadores JavaScript obtêm um modelo de programação duradouro enquanto continuam a usar as suas construções linguísticas e primitivas de bibliotecas familiares.

A capacidade de executar JavaScript diretamente no motor da base de dados proporciona desempenho e execução transacional das operações da base de dados contra os itens de um contentor. Além disso, como o motor de base de dados Azure Cosmos DB suporta nativamente JSON e JavaScript, não há desfasamento de impedância entre os sistemas de tipos de uma aplicação e a base de dados.

Controlo otimista da concorrência

O controlo otimista de concorrência (OCC) permite-lhe evitar atualizações e eliminações perdidas. Operações concorrentes e conflituosas estão sujeitas ao bloqueio pessimista regular do motor de base de dados alojado pela partição lógica que detém o item. Quando duas operações simultâneas tentam atualizar a versão mais recente de um item dentro de uma partição lógica, uma delas vence e a outra falha. No entanto, se uma ou duas operações que tentaram atualizar simultaneamente o mesmo item tivessem lido anteriormente um valor mais antigo do item, a base de dados não sabe se o valor lido anteriormente por uma ou ambas as operações conflitantes era de facto o valor mais recente do item.

Felizmente, esta situação pode ser detectada com o OCC antes de permitir que as duas operações entrem no limite da transação dentro do motor de base de dados. O OCC protege os seus dados contra alterações acidentais feitas por terceiros. Também impede que outros sobreescrevam acidentalmente as tuas próprias alterações.

Implementar controlo de concorrência otimista usando cabeçalhos ETag e HTTP

Cada item armazenado num contentor Azure Cosmos DB tem uma propriedade definida _etag pelo sistema. O valor do _etag é automaticamente gerado e atualizado pelo servidor sempre que o item é atualizado. _etag pode ser usado com o cabeçalho de pedido fornecido if-match pelo cliente para permitir que o servidor decida se um item pode ser atualizado condicionalmente. Se o valor do cabeçalho if-match coincidir com o valor do cabeçalho _etag no servidor, o item é então atualizado. Se o valor do if-match cabeçalho do pedido já não estiver atual, o servidor rejeita a operação com uma mensagem de resposta "HTTP 412 Falha de Pré-condição". O cliente pode então buscar novamente o item para adquirir a versão atual do item no servidor ou substituir a versão do item no servidor pelo seu próprio valor _etag para o item. Além disso, _etag pode ser usado com if-none-match cabeçalho para determinar se é necessário buscar novamente um recurso.

O valor do _etag item muda sempre que é atualizado. Para operações de substituição de item, if-match deve ser explicitamente expresso como parte das opções de pedido. Para um exemplo, veja o código de exemplo no GitHub. Os _etag valores são verificados automaticamente para todos os itens escritos processados pelo procedimento armazenado. Se for detetado algum conflito, o procedimento armazenado reverte a transação e lança uma exceção. Com este método, ou todas ou nenhumas operações de escrita dentro do procedimento armazenado são aplicadas de forma atômica. Isto é um sinal para a aplicação reaplicar atualizações e tentar novamente o pedido original do cliente.

Controlo otimista da concorrência e distribuição global

As atualizações simultâneas de um item são sujeitas ao OCC pela camada de protocolo de comunicação do Azure Cosmos DB. Para contas da Azure Cosmos DB configuradas para escritas numa única região, o Azure Cosmos DB garante que a versão cliente do item que está a atualizar (ou eliminar) é a mesma que a versão do item no contentor da Azure Cosmos DB. Isto garante que as suas escritas estão protegidas de serem sobrescritas acidentalmente pelas escritas de terceiros e vice-versa. Num ambiente multiutilizador, o controlo otimista de concorrência protege-o de apagar ou atualizar acidentalmente a versão errada de um item. Assim, os itens estão protegidos contra os problemas conhecidos como "atualização perdida" ou "eliminação perdida".

Numa conta Azure Cosmos DB configurada com escritas multi-região, os dados podem ser gravados de forma independente em regiões secundárias se o _etag deles corresponder ao dos dados na região local. Assim que novos dados são inseridos localmente numa região secundária, são então integrados no hub ou região primária. Se a política de resolução de conflitos integrar os novos dados na região central, esses dados são entã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 é revertida para os dados originais e _etag.

Próximos passos

Saiba mais sobre transações em bases de dados e controlo otimista da concorrência: