Ir para o conteúdo

Concorrência e Bloqueio de Eventos

Concorrência e Bloqueio

Por padrão, os eventos são executados simultaneamente. Se dois usuários clicarem no mesmo botão ao mesmo tempo, as execuções de eventos podem se sobrepor. Em algumas situações, pode ser necessário sincronizar eventos. Eventos sincronizados são executados de forma serial, garantindo que apenas um evento sincronizado seja executado por vez. Eventos não sincronizados ainda podem ser executados simultaneamente, mesmo com eventos sincronizados.

Os eventos são sincronizados com bloqueios. Um bloqueio abrange a validação e as ações do evento. Os bloqueios não sincronizam outras regras, como padrões ou regras de visibilidade.

Nota

Em um ambiente multi-servidor, bloqueios distribuídos garantem que os eventos sejam sincronizados em todo o cluster. Ao usar o Redis como o provedor de estado compartilhado, o algoritmo Redlock é usado.

Para habilitar o bloqueio de eventos, marque a opção Usar Bloqueio ao criar ou modificar o evento. Isso habilitará opções de bloqueio adicionais. Usar Bloqueio está disponível na tela de configuração de Evento, clicando em Edge Case.

Cuidado

Tenha cuidado ao escolher se deseja bloquear um evento. A sincronização de eventos impacta negativamente o desempenho.

Nomes de Bloqueio

Bloqueios de eventos são chamados de bloqueios. O nome determina o escopo do bloqueio. Eventos bloqueados que compartilham o mesmo nome serão sincronizados. Isso permite que os desenvolvedores sincronizem vários eventos. Por exemplo, os desenvolvedores podem sincronizar os eventos Insert, Update e Delete para uma determinada tabela. Eventos de tabelas diferentes podem até ser sincronizados entre si se compartilharem o mesmo nome.

Se o desenvolvedor não especificar um nome de bloqueio, um nome padrão será gerado no tempo de execução. O nome gerado depende se o evento é um evento de nível de tabela ou um evento de nível de linha. Eventos de nível de tabela incluem os eventos intrínsecos Filter e New. Eventos de nível de linha incluem os eventos intrínsecos Insert, Update e Delete, bem como eventos definidos pelo usuário.

Para eventos de nível de tabela, o nome padrão do escopo é o bloqueio para a tabela. Bloquear o evento Filter da tabela, por exemplo, garante que apenas um evento Filter possa ser executado por vez para a tabela fornecida.

Para eventos de nível de linha, o nome padrão scope é o bloqueio para uma linha. Bloquear o evento Update da tabela, por exemplo, garante que apenas um evento Update possa ser executado por vez para uma determinada linha. Dois eventos Update podem ser executados simultaneamente para diferentes linhas na mesma tabela.

Como os nomes de bloqueio são globais, os desenvolvedores devem tomar cuidado para nomear corretamente os nomes de bloqueio. Considere usar o seguinte padrão como uma linha de base ao nomear bloqueios:

data-source-name:table-name:event-name

Por exemplo:

Fulfillment:Orders:Ship

Cuidado

Se dois eventos compartilham o mesmo nome de bloqueio, App Builder emitirá um aviso para evitar colisões acidentais.

Os nomes de bloqueio suportam interpolação de string. A interpolação de string substitui valores da linha atual no nome do bloqueio. Normalmente, os valores da chave primária da linha são substituídos no nome para criar bloqueios com escopo de linha.

A sintaxe de interpolação de string é:

{{ nome-da-coluna }}

Por exemplo, dado o seguinte nome de bloqueio:

Fulfillment:Orders:Ship:{{Id do pedido }}

O nome do bloqueio de tempo de execução pode ser parecido com este:

Fulfillment:Orders:Ship:1234

Expiração do Bloqueio

Normalmente, os bloqueios são mantidos até que o evento seja concluído, com sucesso ou não. Se o evento não for concluído em tempo hábil, isso afetará a disponibilidade do sistema. Para atenuar isso, os bloqueios de eventos expiram. Se o evento não for concluído dentro do período de expiração, o bloqueio será liberado. Observe, no entanto, que o evento pode continuar a ser executado.

A expiração padrão é de 10 segundos. Os desenvolvedores podem alterar a expiração conforme necessário. Deve-se ter cuidado com valores de expiração mais altos.

Bloqueio de Espera

Os bloqueios são exclusivos: apenas um evento pode adquirir e manter um determinado bloqueio por vez. Outros eventos que tentam adquirir o bloqueio são enfileirados. Eles permanecerão na fila até adquirirem o bloqueio por sua vez ou até que o período de espera do bloqueio tenha expirado.

A espera de bloqueio padrão é de 10 segundos. Os desenvolvedores podem alterar a espera conforme necessário. Se a expiração for relativamente baixa, considere usar um valor igual à expiração. Se a expiração for alta, considere usar um valor baixo para o período de espera do bloqueio. Em outras palavras, se o bloqueio deve durar apenas alguns segundos, os usuários geralmente estão dispostos a esperar que o bloqueio fique disponível. Se, por outro lado, o bloqueio deve durar um minuto ou mais, geralmente é preferível expirar a espera mais cedo e notificar o usuário.

Se o tempo limite de espera do bloqueio for atingido, o usuário verá um alerta de mensagem: "O evento foi cancelado":

Herança de Bloqueio

Eventos suportam herança. As validações e ações definidas em uma tabela física são herdadas por eventos de objeto de dados do mesmo nome. Eventos também herdam configuração de bloqueio. Se o evento Update da tabela física estiver bloqueado, então o evento Update do objeto de dados também estará bloqueado.

A herança de bloqueio se aplica ao evento Save também. O evento Save não é um evento de primeira classe. Em vez disso, suas validações e ações são mescladas nos eventos Insert e Update no tempo de execução. Isso permite que os desenvolvedores registrem uma regra uma vez e a apliquem a inserções e atualizações. Da mesma forma, bloquear o evento Save bloqueará os eventos Insert e Update.

App Builder sintetiza um evento Change em tempo de execução usando validações dos eventos Insert ou Update. O evento Change é executado quando um usuário modifica um valor de campo. Se o evento Insert ou Update estiver bloqueado, o evento Change também será bloqueado.