Lavorare con il bloccaggio ottimistico ORDA

Tradotto automaticamente da Deepl

4D v17 introduce ORDAun’importante evoluzione di 4D che sta aprendo un mondo di nuove possibilità per gli sviluppatori di 4D. Uno dei vantaggi dell’uso di ORDA è legato al blocco dei record, perché ORDA offre la possibilità di scegliere tra il blocco ottimistico e quello pessimistico. Dopo aver introdotto i meccanismi di locking di ORDA, continuiamo la serieORDA per farvi scoprire come lavorare in modo efficiente con il locking ottimistico con ORDA.

Esempio: chiusura ottimistica con ORDA

Il locking ottimistico in poche parole

Nella modalità di chiusura ottimistica, i record non vengono bloccati esplicitamente prima di essere aggiornati.

Il blocco ottimistico si basa sul timbro dei record. Ogni record ha un timbro interno che viene incrementato automaticamente ogni volta che un record viene salvato nel database. Se un record è stato aggiornato da quando è stata caricata un’entità, i metodi save(), drop() e lock() restituiranno un codice di stato specifico che indica che il timbro è cambiato.

REGISTRI ED ENTITÀ

Come promemoria, un record è il record fisico nel database a cui si accede tramite un’entità. Un’entità è un riferimento a un record (vedere la sezione Entità nel glossario). I record vengono bloccati e sbloccati attraverso le entità.

Esempio di codice

Nell’esempio che segue, gestiamo due scenari in cui il metodo save() fallisce.

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 ("Qualcuno ha aggiornato il record da quando è stato caricato")
//The record is locked by another process
: ($status.status=dk status locked)
alert ("Qualcuno ha bloccato il record")
End case
end if
end if

CASO 1: L’ENTITÀ È CAMBIATA

Se il record è stato aggiornato nel database da quando è stata caricata l’entità, l’oggetto $status restituito sarà il seguente:

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

CASO 2: L’ENTITA’ è già bloccata

Se il record nel database è già bloccato da un altro processo, l’oggetto $status restituito sarà il seguente:

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

Scenari comuni

Per accompagnare il metodo save() il metodo, ORDA fornisce un’opzione molto utile: dk auto merge.

dk auto merge tenta di unire automaticamente gli aggiornamenti effettuati in un’entità caricata in memoria con quelli effettuati sul record del database. Tuttavia, potrebbe fallire se nell’entità caricata si aggiornano le stesse proprietà che un altro utente ha aggiornato nel record del database.

Pertanto, offriamo due opzioni per gestire questo problema.

1- Sovrascrivere gli aggiornamenti effettuati nel database

Nell’esempio seguente, il metodo save() con dk auto merge fallisce.

Siamo certi di voler sovrascrivere gli aggiornamenti effettuati nel database da un altro processo.

Questo caso viene gestito da:

1- Prima di salvare, si utilizza il metodo clone(). Questo crea un nuovo riferimento alla nostra entità aggiornata. È utile creare una copia di un’entità per riutilizzarla in seguito.

Quando il metodo save() fallisce, noi:

2- Usiamo il metodo reload() per ricaricare l’entità dal record del database, in modo da ottenere un timbro aggiornato.

3- Utilizzando l’entità clonata, riapplichiamo gli aggiornamenti.

4- Salviamo nuovamente l’entità e verifichiamo lo stato restituito.

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

If ($employee#Null)
// Update the last name
$employee .lastName:="Dunaway"
// Clone the loaded entity
$clonedEmployee :=$employee.clone()
// Save the entity with auto merge option
:=$employee.save(dk auto merge)
// The save action fails
While (Not($status.success))
// The auto merge failed
If $status($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
:=$employee.save(dk auto merge)
End if
End while
End if

2- COSTRUIRE UN’INTERFACCIA UTENTE PER GESTIRE MANUALMENTE I CONFLITTI TRA UN’ENTITÀ E I REGISTRI

ORDA fornisce metodi utili per aiutare a costruire un’interfaccia che permetta agli utenti di scegliere tra i loro aggiornamenti e altri fatti nello stesso momento.

Ecco una rapida panoramica di questi metodi. Per maggiori dettagli, consultare la documentazione.

  • touchedAttributes() metodo: restituisce gli attributi a cui si è acceduto da quando si è caricata o salvata un’entità.
  • diff() metodo: confronta due entità

Nell’HDI fornito, si vedrà come costruire un’interfaccia di questo tipo.

Avatar
- Product Owner - Marie-Sophie Landrieu-Yvert è entrata a far parte del team 4D Product come Product Owner nel 2017. In qualità di Product Owner, è incaricata di scrivere le storie degli utenti e di tradurle in specifiche funzionali. Il suo ruolo è anche quello di assicurarsi che l'implementazione della funzionalità fornita soddisfi le esigenze del cliente.Marie-Sophie si è laureata presso la scuola di ingegneria ESIGELEC e ha iniziato la sua carriera come ingegnere presso IBM nel 1995. Ha partecipato a vari progetti (di manutenzione o di costruzione) e ha lavorato come sviluppatrice Cobol. In seguito ha lavorato come progettista UML e sviluppatore Java. Ultimamente i suoi ruoli principali erano l'analisi e la scrittura dei requisiti funzionali, il coordinamento dei team di business e di sviluppo.