Impedindo atualizações perdidas

Objective

After completing this lesson, you will be able to use Etags para se proteger contra a perda de dados

Controle de processamento paralelo

A seguir, queremos obter uma visão geral das opções que o CAP oferece para garantir a integridade dos dados quando modificações simultâneas são executadas simultaneamente.

Os tempos de execução do CAP suportam diferentes maneiras de evitar situações de atualização perdida, como documentado no vídeo a seguir.

Bloqueio otimista

Começamos com o conceito de bloqueio otimista, que é baseado em ETags (tags de entidade). Para ativar ETags para uma entidade de modelo, adicione a anotação @odata.etag a um elemento da definição de entidade.

No exemplo mostrado, o elemento modifiedAt do aspecto gerenciado é definido como elemento ETag para a entidade Books e a entidade Authors. A diretiva annotate é usada para isso, o que permite que as definições existentes sejam anotadas.

Nota

Os elementos cujo conteúdo é modificado de forma única cada vez que um registro de dados é atualizado são adequados como elemento ETag. Portanto, o elemento modifiedAt do aspecto gerenciado predefinido é um bom candidato. Você também pode usar contadores de atualização ou UUIDs, que são recalculados em cada atualização.

A ideia de uma ETag é identificar uma versão específica de uma entidade, no nosso exemplo a versão de um livro ou de um autor. Isso pode ser utilizado para garantir a integridade dos dados, como explicado no exemplo a seguir, sem usar bloqueios.

Suponha que recuperamos um autor específico por meio da seguinte solicitação porque queremos modificar seus dados:

Code Snippet
1
GET Authors(18f76942-bfb3-40c5-8300-f999f14e9cc2)

Com esta solicitação, a versão do autor, ou seja, o valor do elemento ETag modifiedAt, é automaticamente retornada por meio do cabeçalho de resposta HTTP ETag , por exemplo:

Code Snippet
1
ETag: W/"2024-03-15T11:30:48.069Z"

Para regravar dados modificados no autor, o valor ETag recebido é utilizado da seguinte forma no cabeçalho HTTP If-Match do pedido de modificação correspondente:

Code Snippet
1234567
PUT Authors(18f76942-bfb3-40c5-8300-f999f14e9cc2) If-Match: W/"2024-03-15T11:30:48.069Z" Content-Type: application/json { ... }

Em seguida, o CAP verifica se o conteúdo do elemento modifiedAt foi modificado nesse meio tempo. Caso contrário, os dados do autor são modificados no banco de dados e o campo modifiedAt ETag é atualizado. Em caso afirmativo, isso significa que o autor foi modificado por meio de outra solicitação desde que os dados foram lidos. Por isso, CAP cancela o pedido de modificação e define o código de status 412 (condição prévia falhada) para a resposta HTTP. O corpo da resposta contém um erro semelhante ao seguinte:

JSON
12345
"error": { "code": "412", "message": "Precondition Failed", "@Common.numericSeverity": 4 }

Bloqueio pessimista

O bloqueio otimista garante a integridade dos dados no caso de modificações simultâneas por meio de diferentes solicitações.

Por outro lado, o bloqueio pessimista garante a integridade dos dados no caso de modificações simultâneas por meio de transações simultâneas. O bloqueio pessimista permite que você bloqueie dados para que outras transações sejam bloqueadas para modificar os dados de qualquer forma.

O CAP utiliza bloqueios de banco de dados para bloqueio pessimista, pelo qual é efetuada uma distinção entre bloqueios exclusivos e bloqueios compartilhados.

Os registros de dados exclusivamente bloqueados não podem ser modificados nem lidos por outras transações. Os bloqueios exclusivos são definidos quando os registros de dados são lidos do banco de dados. O API de consulta do CAP fornece o método forUpdate() para esse fim.

Nota

A construção e a execução de consultas serão discutidas posteriormente.

Os bloqueios compartilhados também impedem atualizações simultâneas por transações paralelas. No entanto, eles permitem que todas as transações leiam os registros de dados bloqueados.

Para definir bloqueios compartilhados, a API de consulta fornece o método forShareLock() .

Os bloqueios adquiridos (exclusivos ou compartilhados) são liberados quando a transação atual é concluída, ou seja, confirmados ou revertidos.

Nota

Bloqueio pessimista não suportado pelo SQLite.

Demonstração e exercício: adicionar controle otimista de concorrência

Nota

Como exercício, execute as instruções passo a passo na demonstração a seguir no SAP Business Application Studio.

Como ponto de partida para o exercício, utilize o resultado do exercício anterior Implementar validação de entrada se você o tiver concluído com êxito. Como alternativa, você também pode utilizar a ramificação 8_input_Validation do seguinte repositório GitHub como ponto de partida:

https://github.com/SAP-samples/cap-development-learning-journey

A implementação completa da simulação pode ser encontrada no ramo 9_concurrency_control do repositório GitHub.

Informações detalhadas sobre o conteúdo do repositório e como usá-lo podem ser encontradas aqui.

Assista ao vídeo para ver como adicionar controle otimista de concorrência.