Travailler avec le verrouillage optimiste ORDA

Traduit automatiquement de Deepl

4D v17 introduit ORDAORDA, une évolution majeure de 4D qui ouvre un monde de nouvelles possibilités pour les développeurs 4D. L’un des avantages de l’utilisation d’ORDA est lié au verrouillage des enregistrements, car ORDA offre le choix entre un verrouillage optimiste et pessimiste. Après avoir présenté les mécanismes de verrouillage d’ORDA, nous continuons la sérieORDA afin que vous puissiez découvrir comment travailler efficacement avec le verrouillage optimiste avec ORDA.

Exemple : verrouillage optimiste avec ORDA

Le verrouillage optimiste en quelques mots

En mode de verrouillage optimiste, les enregistrements ne sont pas explicitement verrouillés avant d’être mis à jour.

Le verrouillage optimiste s’appuie sur le cachet des enregistrements. Chaque enregistrement possède un cachet interne qui est automatiquement incrémenté chaque fois qu’un enregistrement est sauvegardé dans la base de données. Si un enregistrement a été mis à jour depuis que vous avez chargé une entité, les méthodes save(), drop() et lock() renverront un code d’état spécifique indiquant que le cachet a changé.

ENREGISTREMENTS ET ENTITÉS

Pour rappel, un enregistrement est l’enregistrement physique de la base de données auquel on accède par le biais d’une entité. Une entité est une référence sur un enregistrement (voir la section Entité dans le glossaire). Les enregistrements sont verrouillés et déverrouillés par les entités.

Exemple de code

Dans l’exemple ci-dessous, nous gérons deux scénarios où la méthode save() échoue.

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 ("Quelqu'un a mis à jour l'enregistrement depuis que vous l'avez chargé")
//The record is locked by another process
: ($status.status=dk status locked)
alert ("Quelqu'un a verrouillé l'enregistrement")
End case
end if
end if

CAS 1 : L’ENTITÉ A CHANGÉ

Si l’enregistrement a été mis à jour dans la base de données depuis que vous avez chargé l’entité, l’objet $status renvoyé sera le suivant :

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

CAS 2 : L’ENTITÉ est déjà verrouillée

Si l’enregistrement dans la base de données est déjà verrouillé par un autre processus, l’objet retourné $status sera le suivant :

{	 	 
 "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	 	 
}

Scénarios communs

Pour accompagner la save() méthode, ORDA fournit une option très utile : dk auto merge.

dk auto merge tente de fusionner automatiquement les mises à jour effectuées dans une entité chargée en mémoire avec celles effectuées sur l’enregistrement dans la base de données. Cependant, cela peut échouer si vous avez mis à jour les mêmes propriétés dans votre entité chargée que celles qu’un autre utilisateur a mises à jour dans l’enregistrement de la base de données.

Par conséquent, nous proposons deux options pour gérer cette situation.

1- SURPRENDRE LES MISES À JOUR EFFECTUÉES DANS LA BASE DE DONNÉES

Dans l’exemple ci-dessous, la méthode save() avec la méthode dk auto merge échoue.

Nous sommes certains de vouloir remplacer les mises à jour effectuées dans la base de données par un autre processus.

Nous gérons ce cas en :

1- Avant de sauvegarder, nous utilisons la méthode clone(). Cela crée une nouvelle référence sur notre entité mise à jour. Il est utile de faire une copie d’une entité pour la réutiliser plus tard.

Lorsque la méthode save() échoue, nous

2- Utiliser la méthode reload() pour recharger notre entité à partir de l’ enregistrement de la base de données afin d’obtenir un cachet à jour.

3- En utilisant l’entité clonée, nous réappliquons nos mises à jour.

4- Nous sauvegardons à nouveau l’entité et testons le statut retourné.

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- CONSTRUIRE UNE INTERFACE UTILISATEUR POUR GÉRER AUTOMATIQUEMENT LES CONFLITS ENTRE UNE ENTITÉ et DES ENREGISTREMENTS

ORDA fournit des méthodes utiles pour vous aider à construire une interface permettant aux utilisateurs de choisir entre leurs mises à jour et d’autres effectuées en même temps.

Voici un aperçu rapide de ces méthodes. Jetez un coup d’œil à la documentation pour plus de détails.

  • touchedAttributes() method : retourne les attributs qui ont été accédés depuis que vous avez chargé ou sauvegardé une entité.
  • diff() méthode : compare deux entités

Dans l’IDH fournie, vous verrez comment construire une telle interface.

Avatar
- Product Owner - Marie-Sophie Landrieu-Yvert a rejoint l'équipe de 4D Product en tant que Product Owner en 2017. En tant que Product Owner, elle est en charge de rédiger les user stories puis de les traduire en spécifications fonctionnelles. Son rôle est également de s'assurer que l'implémentation de la fonctionnalité livrée répond au besoin du client.Marie-Sophie est diplômée de l'école d'ingénieur ESIGELEC et a commencé sa carrière en tant qu'ingénieur chez IBM en 1995. Elle a participé à divers projets (projets de maintenance ou de construction) et a travaillé en tant que développeur Cobol. Elle a ensuite travaillé en tant que concepteur UML et développeur Java. Dernièrement, ses principaux rôles étaient d'analyser et de rédiger des exigences fonctionnelles, de coordonner les équipes commerciales et de développement.