Controle de transações e simultaneidade otimista
APLICA-SE A: NoSQL
As transações do banco de dados oferecem um modelo de programação seguro e previsível para lidar com alterações simultâneas aos dados. Os bancos de dados relacionais tradicionais, como o SQL Server, permitem que você escreva a lógica de negócios usando procedimentos armazenados e/ou gatilhos, envie-a para o servidor para execução diretamente do mecanismo de banco de dados. Com bancos de dados relacionais tradicionais, é necessário lidar com duas linguagens de computador diferentes – a linguagem de programação de aplicativo (não transacional), como JavaScript, Python, C#, Java, etc., e a linguagem de programação transacional (como T-SQL), nativamente executada pelo banco de dados.
O mecanismo de banco de dados no Azure Cosmos DB dá suporte completo a transações em conformidade ACID (atomicidade, consistência, isolamento, durabilidade) com isolamento de instantâneo. Todas as operações de banco de dados dentro do escopo da partição lógica de um contêiner são executadas de maneira transacional dentro do mecanismo de banco de dados hospedado pela réplica da partição. Essas operações incluem operações de gravação (atualização de um ou mais itens dentro da partição lógica) e de leitura. A tabela a seguir ilustra diferentes operações e tipos de transação:
Operação | Tipo de operação | Transação de item único ou de vários itens |
---|---|---|
Inserir (sem um pré/pós-gatilho) | Gravar | Transação de item único |
Inserir (com um pré/pós-gatilho) | Gravar e ler | Transação de vários itens |
Substituir (sem um pré/pós-gatilho) | Gravar | Transação de item único |
Substituir (com um pré/pós-gatilho) | Gravar e ler | Transação de vários itens |
Upsert (sem um pré/pós-gatilho) | Gravar | Transação de item único |
Upsert (com um pré/pós-gatilho) | Gravar e ler | Transação de vários itens |
Excluir (sem um pré/pós-gatilho) | Gravar | Transação de item único |
Excluir (com um pré/pós-gatilho) | Gravar e ler | Transação de vários itens |
Executar procedimento armazenado | Gravar e ler | Transação de vários itens |
O sistema iniciou a execução de um procedimento de mesclagem | Gravar | Transação de vários itens |
O sistema iniciou a execução da exclusão de itens com base na expiração (vida útil) de um item | Gravar | Transação de vários itens |
Ler | Ler | Transação de item único |
Feed de alterações | Ler | Transação de vários itens |
Leitura paginada | Ler | Transação de vários itens |
Consulta paginada | Ler | Transação de vários itens |
Executar UDF como parte da consulta paginada | Ler | Transação de vários itens |
Transações de vários itens
O Azure Cosmos DB permite gravar procedimentos armazenados, pré/pós-gatilhos, UDFs (funções definidas pelo usuário) e procedimentos de mesclagem em JavaScript. O Azure Cosmos DB dá suporte nativo à execução de JavaScript dentro de seu mecanismo de banco de dados. É possível registrar procedimentos armazenados, pré/pós-gatilhos, UDFs (funções definidas pelo usuário) e procedimentos de mesclagem em um contêiner e executá-los posteriormente de maneira transacional dentro do mecanismo de banco de dados do Azure Cosmos DB. Gravar uma lógica de aplicativo em JavaScript permite a expressão natural do fluxo de controle, escopo de variáveis, atribuição e integração de primitivos de manuseio de exceções dentro de transações do banco de dados diretamente na linguagem JavaScript.
Os procedimentos armazenados baseados em JavaScript, gatilhos, UDFs e procedimentos de mesclagem são encapsulados dentro de uma transação ACID ambiente com isolamento de instantâneos em todos os itens dentro da partição lógica. No decorrer de sua execução, se o programa JavaScript gerar uma exceção, toda a transação será abortada e revertida. O modelo de programação resultante é simples, porém, poderoso. Os desenvolvedores de JavaScript obtêm um modelo de programação durável, ao mesmo tempo em que utilizam os construtores de linguagem e primitivas de biblioteca com os quais estão familiarizados.
A capacidade de executar JavaScript diretamente dentro do mecanismo de banco de dados oferece desempenho e execução transacional de operações do banco de dados com relação aos itens de um contêiner. Além disso, como o mecanismo de banco de dados do Azure Cosmos DB dá suporte nativo a JSON e JavaScript, não há incompatibilidade de impedância entre os sistemas do tipo de um aplicativo e o banco de dados.
Controle de simultaneidade otimista
O controle de simultaneidade otimista permite que você evite a perda de atualizações e exclusões. Operações simultâneas e conflitantes estão sujeitas ao bloqueio pessimista regular do mecanismo de banco de dados hospedado pela partição lógica da qual o item faz parte. Quando duas operações simultâneas tentarem atualizar a última versão de um item em uma partição lógica, uma delas vencerá e a outra falhará. No entanto, se uma ou duas operações tentando atualizar simultaneamente o mesmo item tivessem lido anteriormente um valor mais antigo do item, o banco de dados não saberia se o valor lido anteriormente por qualquer uma ou por ambas as operações conflitantes era de fato o valor mais recente do item. Felizmente, essa situação pode ser detectada com o OCC (Controle de Simultaneidade Otimista) antes de permitir que as duas operações entrem no limite de transação dentro do mecanismo de banco de dados. O OCC protege seus dados contra alterações de substituição acidental feitas por outras pessoas. Ele também impede outras pessoas de substituir acidentalmente suas próprias alterações.
Implementar controle de simultaneidade otimista usando cabeçalhos ETag e HTTP
Cada item armazenado em um contêiner do Azure Cosmos DB tem uma propriedade _etag
definida por sistema. O valor do _etag
é gerado e atualizado automaticamente pelo servidor toda vez que o item é atualizado. _etag
pode ser usado com o cabeçalho de solicitação if-match
fornecido pelo cliente para permitir que o servidor decida se um item pode ser atualizado condicionalmente. Se o valor do cabeçalho if-match
corresponder ao valor de _etag
no servidor, então o item será atualizado. Se o valor do cabeçalho de solicitação if-match
não for mais atual, o servidor rejeitará a operação com uma mensagem de resposta "HTTP 412 Falha de pré-condição". O cliente, então, poderá buscar novamente o item para adquirir a versão atual dele no servidor ou substituir a versão de item no servidor por seu próprio valor _etag
para o item. Além disso, pode-se utilizar _etag
com o cabeçalho if-none-match
para determinar se uma nova busca de um recurso é necessária.
O valor da _etag
do item muda sempre que o item é atualizado. Para operações de item de substituição, if-match
deve ser explicitamente expresso como parte das opções de solicitação. Para obter um exemplo, confira o código de exemplo no GitHub. Os valores _etag
são implicitamente verificados para todos os itens gravados tocados pelo procedimento armazenado. Se qualquer conflito for detectado, o procedimento armazenado reverterá a transação e gerará uma exceção. Com esse método, toda ou nenhuma gravação dentro do procedimento armazenado é aplicada de maneira atômica. Isso é um sinal para o aplicativo reaplicar atualizações e repetir a solicitação original do cliente.
Controle 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 gravações de região única, o Azure Cosmos DB garante que a versão do lado do cliente do item que você está atualizando (ou excluindo) seja igual à versão do item no contêiner do Azure Cosmos DB. Isso garante que suas gravações sejam protegidas contra substituições acidentais realizadas pelas gravações de outras pessoas e vice-versa. Em um ambiente multiusuário, o controle de simultaneidade otimista protege você contra a exclusão ou a atualização acidental da versão incorreta de um item. Como tal, os itens são protegidos contra problemas infames de "atualização perdida" ou "exclusão perdida".
Em uma conta do Azure Cosmos DB configurada com gravações de várias regiões, os dados podem ser confirmados independentemente em regiões secundárias se houver correspondências _etag
com os dados na região local. Depois que novos dados são confirmados localmente em uma região secundária, eles são mesclados no Hub ou na região primária. Se a política de resolução de conflitos mescla os novos dados na região do Hub, esses 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
.
Próximas etapas
Saiba mais sobre controle de transações e simultaneidade otimista do banco de dados nos seguintes artigos: