Trabalhar com o bloqueio ORDA optimista

Tradução automática de Deepl

4D v17 introduz ORDAUma grande evolução em 4D que abre um mundo de novas possibilidades para os criadores 4D. Um dos benefícios da utilização da ORDA está relacionado com o bloqueio de registos, porque a ORDA oferece uma escolha entre o bloqueio optimista e pessimista. Depois de termos introduzido os mecanismos de bloqueio ORDA, continuamos a sérieORDA para que possa descobrir como trabalhar eficientemente com o bloqueio optimista com ORDA.

Exemplo: bloqueio optimista com ORDA

Fecho óptimo em poucas palavras

No modo de bloqueio optimista, os registos não são explicitamente bloqueados antes de serem actualizados.

O bloqueio optimista depende do carimbo dos registos . Cada registo tem um carimbo interno que é automaticamente aumentado cada vez que um registo é guardado na base de dados. Se um registo tiver sido actualizado desde que carregou uma entidade, os métodos save(), drop(), e lock() devolverão um código de estado específico indicando que o carimbo mudou.

GRAVOS E ENTIDADES

Como lembrete, um registo é o registo físico na base de dados que é acedido através de uma entidade. Uma entidade é uma referência num registo (ver secção Entidade no glossário). Os registos são bloqueados e desbloqueados através de entidades.

Exemplo de código

No exemplo abaixo, lidamos com dois cenários em que a save() método falha.

C_OBJECT($status;$employee)

// Get the first employee whose last name is "Smith"
$employee :=ds.Employee.query("lastName=:1"; "Smith").first()
If ($employee#Null)
$employee .lastName:="Wates" // Update employee's last name
$status :=$employee.save() // Save employee
if (Not($status.success)) // The save action fails
Case of
// The record has been updated in database since the entity was loaded
: ($status.status=dk status stamp has changed)
alert ("Alguém actualizou o registo desde que o carregou")
//The record is locked by another process
: ($status.status=dk status locked)
alert ("Alguém bloqueou o registo")
End case
end if
end if

CASO 1: ENTIDADE MUDOU

Se o registo tiver sido actualizado na base de dados desde que carregou a entidade, o objecto devolvido $status será o seguinte:

{
 "status": 2,
 "statusText": "Stamp has changed",
 "success": false
}

CASO 2: A ENTIDADE já está bloqueada

Se o registo na base de dados já estiver bloqueado por outro processo, o objecto devolvido $status será o seguinte:

{	 	 
 "status": 3,	 	 
 "statusText": "Already Locked",	 	 
 "lockKind": 1,	 	 
 "lockKindText": "Locked By Record",	 	 
 "lockInfo": {	 	 
     "task_id": 5,	 	 
     "user_name": "Mary Smith",	 	 
     "user4d_id": 1,	 	 
     "host_name": "iMac27-Program6",	 	 
     "task_name": "P_10",	 	 
     "client_version": -1610541312	 	 
 },	 	 
 "success": false	 	 
}

Cenários COMUNS

Para acompanhar o save() método, ORDA fornece uma opção muito útil: dk auto merge.

dk auto merge tenta fundir automaticamente as actualizações feitas numa entidade carregada em memória com as feitas no registo na base de dados. Hoever, pode falhar se actualizar as mesmas propriedades na sua entidade carregada como outro utilizador actualizado no registo na base de dados.

Por conseguinte, oferecemos duas opções para gerir isto.

1- SOBRE AS ACTUALIZAÇÕES FEITAS NA BASE DE DADOS

No exemplo abaixo, o save() método com dk auto merge falha.

Estamos certos de que queremos substituir as actualizações feitas na base de dados por outro processo.

Gerimos este caso por:

1- Antes de poupar, utilizamos o clone() método. Isto cria uma nova referência sobre a nossa entidade actualizada. É útil fazer uma cópia de uma entidade para a reutilizar mais tarde.

Quando o save() método falha, nós:

2- Utilizamos o reload() método para recarregar a nossa entidade a partir do registo da base de dados para que possamos obter um carimbo actualizado.

3- Utilizando a entidade clonada, reaplicamos as nossas actualizações.

4- Salvamos a entidade de novo e testamos o estado devolvido.

C_OBJECT($status;$employee;$clonedEmployee)
// Get the first employee whose last name is "Smith"
$employee :=ds.Employee.query("lastName=:1"; "Smith@").first()

If ($employee#Null)
// Update the last name
$employee .lastName:="Dunaway"
// Clone the loaded entity
$clonedEmployee :=$employee.clone()
// Save the entity with auto merge option
$status :=$employee.save(dk auto merge)
// The save action fails
While (Not($status.success))
// The auto merge failed
If ($status.status=dk status automerge failed)
// Reload the entity. The stamp will be updated
$employee .reload()

// Reapply the update on last name
$employee .lastName:=$clonedEmployee.lastName
// Save the entity
$status :=$employee.save(dk auto merge)
End if
End while End if

2- CONSTRUIR UTILIZADORES INTERFACE PARA GERIR CONFLITOS MANUALMENTE ENTRE ENTIDADES e GRAVADOS

ORDA fornece métodos úteis para o ajudar a construir uma interface que permite aos utilizadores escolher entre as suas actualizações e outras feitas ao mesmo tempo.

Aqui está uma rápida visão geral destes métodos. Veja a documentação para mais detalhes.

  • touchedAttributes() método: devolve atributos que foram acedidos desde que se carregou ou salvou uma entidade.
  • diff() método: compara duas entidades

No IDH fornecido, verá como construir tal interface.

Avatar
• Proprietário do produto - Marie-Sophie Landrieu -Yvert entrou ao time 4D Product como Proprietária do Produto em 2017. Como tal, está a cargo de escrever as histórias dos usuários e depois traduzi-las em especificações funcionais. Seu papel também é garantir que a implementação da funcionalidade entregue cumpra com as necessidades do cliente. Marie-sophie se formou na Escola de Engenharia de ESIGELEC e começou sua carreira como engenheira da IBM em 1995. Participou em vários projetos (de manutenção e criação) e trabalhou como desenvolvedora de Cobol. Depois trabalhou como designer de UML e desenvolvedora de Java. Suas principais funções foram analisar e redigir requisitos funcionais, coordenar os times de negócio e de desenvolvimento.