Práce s optimistickým zamykáním ORDA

Automaticky přeloženo z Deepl

4D v17 zavádí ORDA, což je významný vývoj v 4D, který otevírá vývojářům 4D svět nových možností. Jedna z výhod používání ORDA souvisí se zamykáním záznamů, protože ORDA nabízí volbu mezi optimistickým a pesimistickým zamykáním. Po představení mechanismů zamykání ORDA pokračujeme v seriálu oORDA, abyste zjistili, jak efektivně pracovat s optimistickým zamykáním pomocí ORDA.

Příklad: optimistické zamykání pomocí ORDA

Optimistické zamykání v několika slovech

V režimu optimistického zamykání nejsou záznamy před aktualizací explicitně zamykány .

Optimistické zamykání se spoléhá na razítko záznamů . Každý záznam má interní razítko, které se automaticky inkrementuje při každém uložení záznamu do databáze. Pokud byl záznam od načtení entity aktualizován, metody save(), drop() a lock() vrátí specifický stavový kód označující, že se razítko změnilo.

ZÁZNAMY A ENTITY

Jen pro připomenutí, záznam je fyzický záznam v databázi, ke kterému se přistupuje prostřednictvím entity. Entita je odkaz na záznam (viz část Entita ve slovníku pojmů). Záznamy se zamykají a odemykají prostřednictvím entit.

Příklad kódu

V následujícím příkladu zpracováváme dva scénáře, v nichž se save() metoda selže.

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 ("Někdo aktualizoval záznam od doby, kdy jste jej načetli")
//The record is locked by another process
: ($status.status=dk status locked)
alert ("Někdo záznam uzamkl")
End case
. end if
end if

PŘÍPAD 1: SUBJEKT SE ZMĚNIL

Pokud byl záznam v databázi od načtení entity aktualizován, bude vrácený objekt $status vypadat následovně:

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

PŘÍPAD 2: ENTITA je již uzamčena

Pokud je záznam v databázi již uzamčen jiným procesem, bude vrácený objekt $status vypadat následovně:

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

SPOLEČNÉ scénáře

Abychom doprovodili save() metody, ORDA poskytuje velmi užitečnou možnost: dk auto merge.

dk auto merge se pokusí automaticky sloučit aktualizace provedené v entitě načtené v paměti s aktualizacemi provedenými na záznamu v databázi. Může však selhat, pokud jste v načtené entitě aktualizovali stejné vlastnosti jako jiný uživatel v záznamu v databázi.

Proto nabízíme dvě možnosti, jak se s tímto problémem vypořádat.

1- PŘEHLÉDNOUT AKTUALIZACE PROVEDENÉ V DATABÁZI

V níže uvedeném příkladu save() metoda s dk auto merge selže.

Jsme si jisti, že chceme přepsat aktualizace provedené v databázi jiným procesem.

Tento případ zvládneme:

1- Před uložením použijeme příkaz clone(). Ta vytvoří novou referenci na naši aktualizovanou entitu. Je to užitečné pro vytvoření kopie entity, abychom ji mohli později znovu použít.

Když se save() metoda selže, provedeme:

2 – použijeme metodu reload() znovu načteme naši entitu ze záznamu v databázi, abychom získali aktuální razítko.

3- Pomocí klonované entity znovu použijeme naše aktualizace.

4- Znovu uložíme entitu a otestujeme vrácený stav.

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- ZABUDOVÁNÍ UŽIVATELSKÉHO ROZHRANÍ PRO RUČNÍ SPRÁVU KONFLIKTŮ MEZI ZAŘÍZENÍMI A ZÁZNAMY.

ORDA poskytuje užitečné metody, které vám pomohou vytvořit rozhraní umožňující uživatelům vybrat si mezi jejich aktualizací a dalšími současně provedenými úkony.

Zde je stručný přehled těchto metod. Podrobnější informace naleznete v dokumentaci.

  • touchedAttributes() Metoda: vrací atributy, ke kterým bylo přistupováno od doby, kdy jste entitu načetli nebo uložili.
  • diff() metoda: porovnává dvě entity

V dodaném HDI uvidíte, jak takové rozhraní sestavit.

Avatar
• Product Owner • Marie-Sophie Landrieu-Yvert se připojila k programovému týmu 4D jako Product Owner v roce 2017. Jako Product Owner má na starosti psaní uživatelských příběhů a jejich převod do funkčních specifikací. Její úlohou je také zajistit, aby implementovaná funkce odpovídala potřebám zákazníka. Marie-Sophie vystudovala inženýrskou školu ESIGELEC a svou kariéru zahájila jako inženýrka v IBM v roce 1995. Podílela se na různých projektech (projekty údržby nebo výstavby) a pracovala jako vývojářka Cobol. Poté pracovala jako UML designer a Java developer. V poslední době byly jejími hlavními rolí analyzovat a psát funkčních požadavky a koordinovat obchodní a vývojové týmy.