Jak jsou implementovány zámky v CzechIdM

V rámci přípravy CzechIdM na vysokou dostupnost proběhla kompletní restrukturalizace systému zámků. Do budoucna počítáme s nasazením CzechIdM na více aplikačních serverů zároveň při vysokém zatížení. V tomto článku se dozvíte o změnách, které proběhly ohledně zámků CzechIdM a jak je případně využít.

Zámek

Zámky slouží v CzechIdM pro regulaci přístupů k entitám. Mají zabránit kolizím, kde by se dva různé procesy snažily změnit zároveň tu samou entitu. Proto datová vrstva, před každým procesem upravení dané entity, vystaví zámek.

Zámek se vždy drží 5 minut, než vyprší. Během této doby má proces čas na to, aby entitu upravil. Když skončí proces s úpravami, navrátí entitu datové vrstvě, ta zámek uvolní a změny uloží.

Rozšíření parametrů zámku

Dříve se k zámku evidoval pouze jediný atribut, a to uživatel, který daný záznam uzamknul. To by v tomto případě již nestačilo. Naplánované úlohy typicky bežící pod stejným systémovým uživatelem admin, z každého serveru snažily zároveň upravovat jednu entitu, čímž by vznikla kolize. Zámky by nepoznaly, že se jedná o rozdílné procesy, protože jediný jejich atribut – uživatel admin, je u obou serverů stejný. Čímž by umožnily paralelní editaci. Proto jsme rozšířili zámky o další atributy jako jsou hostname, process id (PID) a číslo vlákna serveru, na kterém CzechIdM běží. Proto již nebude možné, aby stejný uživatel přihlášený na rozdílných serverech, upravoval zároveň ten stejný záznam.

Čekání na zámky

Poslední provedenou změnou v koncepci zámků byla možnost procesu počkat na uvolnění daného zámku. Všem metodám, které vyžadují zamknutí se dá nyní předat objekt LockWaitSettings. Ten specifikuje parametry čekání, typicky jak dlouho se má proces pokusit čekat na zámek, než se uvolní.

Interně čekání funguje tak, že se proces pokusí uzamknout entitu. Když už je zamknutá, tak se na chvíli uspí a za určitý čas se jí pokusí uzamknout znovu. Toto dělá tak dlouho, než mu vyprší specifikovaný čas. V případě neúspěchu vyhazuje výjimku LockException, kterou musí volající metoda ošetřit.

// Priklad checkout view s maximalnim cekacim casem 3000ms
try {
    Data.checkoutView(View.Type.USER, "john", new LockWaitSettings(3000));
} catch (LockException e) {
    // Nepodarilo se ziskat zamek
}

Závěr

Kdyby jste měli nějaké dotazy ohledně funkčnosti zámků v CzechIdM, neváhejte napsat na info@bcvsolutions.eu.