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.