InterSystems IRIS andmebaas toetab huvitavaid andmestruktuure â globaalid. Sisuliselt on need mitmeastmelised vĂ”tmed koos erinevate lisafunktsioonidega, nagu tehingud, kiired funktsioonid andmepuude lĂ€bimiseks, lukustamine ja oma ObjectScript'i keel.
Rohkem globaalidest artiklisarjas «Globaalid â andmete salvestamise mÔÔgakoolid»:
Mind huvitab, kuidas tehingud globaalides on rakendatud, millised on seal omadused. LÔppude lÔpuks on see tÀiesti erinev andmesalvestamisstruktuur, vÔrreldes tuttavate tabelitega. Oluliselt madalama tasandi.
Kuna on teada, et relatsiooniliste andmebaaside teooria kohaselt peab hea tehingute teostus vastama nÔuetele :
A â Atomite (aatomsus). KĂ”ik tehingus tehtud muutused salvestatakse vĂ”i mitte ĂŒhtegi.
C â Consistency (kooskĂ”la). PĂ€rast tehingu lĂ”petamist peab andmebaasi loogiline seisund olema sisemiselt jĂ€rjekindel. Suurel mÀÀral puudutab see nĂ”ue programmeerijat, kuid SQL-andmebaaside puhul puudutab see ka vĂ€liseid vĂ”tmeid.
I â Isolate (isoleeritus). Samas kĂ€ivitatud tehingud ei tohiks ĂŒksteisele mĂ”ju avaldada.
D â Durable (pĂŒsivus). PĂ€rast tehingu edukat lĂ”petamist ei tohiks madalama taseme probleemid (nĂ€iteks toitekaotused) mĂ”jutada tehingu kĂ€igus muudetud andmeid.
Globaalid on mittesuhtelised andmestruktuurid. Need on loodud ĂŒlivĂ”imsateks toiminguteks vĂ€ga piiratud riistvaral. Uurime, kuidas tehingud globaalides töötavad, kasutades .
Tehingute toetamiseks IRIS-is kasutatakse jÀrgmisi kÀsklusi: , , .
1. Aatomilisus
Aatomilisuse kontrollimine on kÔige lihtsam. Kontrollime andmebaasi kontolt.
Kill ^a
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TCOMMITSeejÀrel teeme jÀrelduse:
Write ^a(1), â â, ^a(2), â â, ^a(3)Saame:
1 2 3KÔik on korras. Aatomilisus on tagatud: kÔik muudatused on salvestatud.
Vaatame ĂŒlesannet keerulisemaks, sisestame vea ja vaatame, kuidas tehing sĂ€ilib, osaliselt vĂ”i ĂŒldse mitte.
Kontrollime aatomilisust veel kord:
Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3SeejÀrel peatame konteineri sundimisega, kÀivitame selle ja vaatame.
docker kill my-irisSee kĂ€sk on praktiliselt samavÀÀrne jĂ”ulise toitevĂ€ljalĂŒlitamisega, kuna saadab SIGKILL protsessi kohese lĂ”petamise signaali.
Kas vÔib juhtuda, et tehing on osaliselt salvestatud?
WRITE ^a(1), ^a(2), ^a(3)
^
^a(1)â Ei, see ei ole salvestatud.
Katsume tagasipöördumise kÀsku:
Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TROLLBACK
WRITE ^a(1), ^a(2), ^a(3)
^
^a(1)Ka see ei ole salvestatud.
2. Sidusus
Kuna globaalsetes andmebaasides luuakse vÔtmed samuti globaalsetele (meeldetuletuseks, et globaal on madalama taseme struktuur andmete salvestamiseks kui relatsiooniline tabel), peab sidususe nÔude tÀitmiseks vÔtme muutmine olema sama tehingu osaks kui globaali muutmine.
NÀiteks on meil globaalsed ^person, kuhu salvestame isikuandmed ja vÔtmena kasutame INN-i.
^person(1234567, âfirstnameâ) = âSergeyâ
^person(1234567, âlastnameâ) = âKamenevâ
^person(1234567, âphoneâ) = â+74995555555
...Kuna soovime kiiret otsingut perekonnanime ja eesnime jÀrgi, lÔime vÔtme ^index.
^index(âKamenevâ, âSergeyâ, 1234567) = 1Et andmebaas oleks sidus, peame isikuandmed lisama jĂ€rgmiselt:
TSTART
^person(1234567, âfirstnameâ) = âSergeyâ
^person(1234567, âlastnameâ) = âKamenevâ
^person(1234567, âphoneâ) = â+74995555555
^index(âKamenevâ, âSergeyâ, 1234567) = 1
TCOMMITSeega, kustutamise puhul peame samuti kasutama tehingut:
TSTART
Kill ^person(1234567)
ZKill ^index(âKamenevâ, âSergeyâ, 1234567)
TCOMMITTeisisĂ”nu, nĂ”uete jĂ€rjepidevuse tĂ€itmine lasub tĂ€ielikult arendaja Ă”lgadel. Kuid kui tegemist on globaalidega â on see normaalne, arvestades nende madalama taseme iseloomu.
3. Isolatsioon
Siinkohal algavad pÔhjalikud probleemid. Paljud kasutajad töötavad sama andmebaasi kallal, muutes samu andmeid.
See olukord on sarnane olukorraga, kus mitmed kasutajad töötavad sama koodirepositooriumi kallal ja ĂŒritavad samal ajal teha muudatusi paljudes failides.
Andmebaas peab seda kĂ”ike reaalajas haldama. Arvestades, et tĂ”sistes ettevĂ”tetes on isegi eraldi inimene, kes vastutab versioonihalduse (harude sulandumine, konfliktide lahendamine jne) eest, ja andmebaasi peaks seda tegema reaalajas, siis on ĂŒlesande keerukus ja andmebaasi ning selle halduskoodi korrektne projekteerimine ilmne.
Andmebaas ei saa mĂ”ista kasutajate teoste tĂ€hendust, et vĂ€ltida konflikte, kui nad töötavad sama andmete kallal. Ta suudab vaid tĂŒhistada ĂŒhe tehingu, mis on vastuolus teisega, vĂ”i tĂ€ita need jĂ€rjestikku.
Veel ĂŒks probleem on see, et tehingu tĂ€itmise ajal (enne kinnitust) vĂ”ib andmebaas olla ĂŒhtlustamata olekus, seetĂ”ttu on soovitatav, et teistel tehingutel ei oleks juurdepÀÀsu ĂŒhtlustamata andmebaasi olekule, mida saavutatakse relatsioonilistes andmebaasides paljusid viise kaudu: lĂ”ikepunktide loomine, mitme versiooni ridade kasutamine jne.
Paralleelse tehingute tĂ€itmise puhul on meil oluline, et nad ei segaks ĂŒksteist. See ongi isoleerimise omadus.
SQL mÀÀratleb 4 isoleerimistaset:
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
Vaatame iga taset eraldi. Iga taseme rakendamise kulud kasvavad peaaegu eksponentsiaalselt.
READ UNCOMMITTED â see on madalaim isoleerimistaseme tase, kuid samas ka kĂ”ige kiirem. Tehingud saavad lugeda ĂŒksteise tekitatud muudatusi.
READ COMMITTED â see on jĂ€rgmine isoleerimistaseme tase, mis on kompromiss. Tehingud ei saa lugeda ĂŒksteise tekitatud muudatusi enne kinnitamist, kuid saavad lugeda pĂ€rast kinnitamist tehtud muudatusi.
Kui meil on pikk tehing T1, mille jooksul toimuvad kinnitused tehingutes T2, T3 ... Tn, mis töötasid sama andmete kallal nagu T1, siis T1-s andmeid kĂŒsides saame me alati erinevaid tulemusi. Seda nĂ€htust nimetatakse mittetĂ€ielikuks lugemiseks.
REPEATABLE READ â selle isolatsioonitaseme juures ei esine korduvat lugemist, kuna iga andmelugemise pĂ€ringu jaoks luuakse andmessnapshot ja sama tehingu jooksul kasutatakse seda snapshot'i andmeid. Kuid selle isolatsiooni taseme puhul on vĂ”imalik lugeda fantoomandmeid. See tĂ€hendab, et on vĂ”imalik lugeda uusi ridu, mis on lisatud paralleelsete kinnitatud tehingute kaudu.
SERIALIZABLE â kĂ”rgeim isolatsioonitase. Selle tunnuseks on see, et tehingus kasutatavad andmed (kas lugemine vĂ”i muutmine) on teistele tehingutele kĂ€ttesaadavad alles pĂ€rast esimeses tehingus lĂ”petamist.
KÀime esmalt lÀbi, kas tehingus toimingud on peastreamist isoleeritud. Avame kaks terminaliakent.
Kill ^t
Write ^t(1)
2
TSTART
Set ^t(1)=2Isolatsiooni pole. Ăks lĂ”im nĂ€eb, mida teeb teine, kes avas tehingu.
Vaadakem, kas erinevate lÔimude tehingud nÀevad, mis toimub nende sees.
Avame kaks terminaliakent ja avame samal ajal kaks tehingut.
kill ^t
TSTART
Write ^t(1)
3
TSTART
Set ^t(1)=3
Paralleelsed tehingud nĂ€evad ĂŒksteise andmeid. Nii saime kĂ”ige lihtsama, aga ka kĂ”ige kiirema isoleerimise taseme READ UNCOMMITED.
PÔhimÔtteliselt sai seda oodata globaalide jaoks, mille puhul on jÔudlus alati peamine prioriteet.
Kuidas siis tegelikult toimida, kui meil on vaja kÔrgemat isoleerimise taset globaalide operatsioonides?
Siin tuleb mĂ”elda, miks isoleerimistaset ĂŒldse vaja on ja kuidas need toimivad.
KÔrgeim isoleerimise tase SERIALIZE tÀhendab, et paralleelselt tÀidetud tehingute tulemus on vÔrreldav nende jÀrjestikuse tÀitmisega, mis garanteerib konfliktide puudumise.
Seda saame teha Ôigete lukustustega ObjectScriptis, mis pakuvad palju erinevaid rakendusi: saame teha tavalisi, jÀrjestikuseid ja mitmeosalisi lukustusi kÀsuga .
Madalamad isoleerimise tasemed on kompromissid, mille eesmÀrk on suurendada andmebaasi töökiirust.
Vaatame, kuidas me saame lukustuste abil saavutada erinevaid isoleerimise tasemeid.
See operaator vÔimaldab mitte ainult eksklusiivsete lukustuste rakendamist, mis on vajalikud andmete muutmiseks, vaid ka nn jagatud lukustusi, mida saavad korraga kasutada mitmed niidid, kui nad peavad lugema andmeid, mida ei tohiks teiste protsesside poolt lugemise ajal muuta.
Lisateave kahefaasilise lukustamismeetodi kohta vene ja inglise keeles:
â
â
Raskus seisneb selles, et tehingu ajal vÔib andmebaasi olek olla kooskÔlmatu, kuid need kooskÔlmatud andmed on nÀhtavad teistele protsessidele. Kuidas seda vÀltida?
Loome lukustuste abil sellised nÀhtavuse aknad, kus andmebaasi olek on kooskÔlas. Ja kÔik juurdepÀÀsud sellistele kooskÔlastatud oleva nÀhtavuse akendele kontrollitakse lukustuste kaudu.
Jagatud lukustused samadele andmetele on korduvkasutatavad â nendele saavad juurdepÀÀsu mitmed protsessid. Need lukustused keelavad muudele protsessidele andmete muutmise, st neid kasutatakse andmebaasi kooskĂ”lastatud oleku akende vormimiseks.
Eksklusiivsed lukud kasutatakse andmete muutmiseks â sellist lukku saab vĂ”tta ainult ĂŒks protsess. Eksklusiivset lukku saab vĂ”tta:
- Iga protsess, kui andmed on vabad
- Ainult see protsess, millel on nende andmete suhtes jagatud lukustus ja kes esimene kĂŒsis eksklusiivset lukku.

Mida kitsam on nĂ€htavusakna, seda kauem peavad teised protsessid ootama, kuid sellel vĂ”ib olla ĂŒhtlasem andmebaasi olek.
READ_COMMITED â selle taseme peamine mĂ”te on see, et me nĂ€eme ainult erinevates voogudes kinnitatud andmeid. Kui andmed teises tehingus pole veel kinnitatud, siis nĂ€eme nende vana versiooni.
See vÔimaldab meil tööd paralleelselt kÀia, selle asemel et oodata lukkude vabastamist.
Ilma eriliste trikkideta ei suuda me IRISes nÀha vana andmeversiooni, seega peame loobuma lukustustest.
Seega peame jagatud lukustuste abil lubama andmete lugemist ainult kooskÔla hetkedel.
Oletame, et meil on kasutajate andmebaas ^person, kes kannavad raha ĂŒksteisele.
RahaĂŒlekande hetk isikute 123 ja 242 vahel:
LOCK +^person(123), +^person(242)
Set ^person(123, amount) = ^person(123, amount) - amount
Set ^person(242, amount) = ^person(242, amount) + amount
LOCK -^person(123), -^person(242)Isiku 123 rahasumma kĂŒsimine enne mahaarvamist peab olema seotud eksklusiivse lukustamisega (vaikimisi):
LOCK +^person(123)
Write ^person(123)Kui tuleb nÀidata konto seisu isiklikus kabinetis, vÔib kasutada jagatud lukustust vÔi jÀtta see kasutamata:
LOCK +^person(123)#âSâ
Write ^person(123)Kuid kui eeldada, et andmebaasi tehingud toimuvad praktiliselt koheselt (meenutame, et globaalid on palju madalama taseme struktuur kui relatiivne tabel), siis on selle taseme vajadus vÀhenenud.
REPEATABLE READ â selle isolatsiooni taseme juures lubatakse, et andmeid vĂ”idakse lugeda mitmeid kordi, mida vĂ”ivad muuta paralleelsed tehingud.
SeetÔttu peame seadma jagatud lukustuse neile andmetele, mida me muudame, ja eksklusiivsed lukustused andmetele, mida me muudame.
Hea on see, et LOCK operaator vĂ”imaldab ĂŒhes kĂ€skluses detailsemalt loetleda kĂ”ik vajalikud lukustused, mida vĂ”ib olla vĂ€ga palju.
LOCK +^person(123, amount)#âSâ
Lugemine ^person(123, amount)teised toimingud (selle ajal ĂŒheaegselt katsetab voog ^person(123, amount), kuid ei Ă”nnestu)
LOCK +^person(123, amount)
muutmine ^person(123, amount)
LOCK -^person(123, amount)
lugemine ^person(123, amount)
LOCK -^person(123, amount)#âSâKui loetleda lukustusi komaga, siis need vĂ”etakse jĂ€rjestikku, kuid kui teha nii:
LOCK +(^person(123),^person(242))siis need vÔetakse atomaarsemalt kÔik korraga.
SERIALIZE â peame lukustusi seadma nii, et lĂ”puks kĂ”ik tehingud, mis omavad ĂŒhiseid andmeid, toimuksid jĂ€rjestikku. Selle lĂ€henemise jaoks peaksid enamik lukustusi olema eksklusiivsed ja katma vĂ€ikseimaid ala globaalses sĂŒsteemis, et saavutada paremat jĂ”udlust.
Kui rÀÀkida rahade mahakandmist globaalsetes ^person, siis selle jaoks on sobiv ainult SERIALIZE eraldusvÔime, kuna raha peab kulutama rangelt jÀrjestikku, vastasel juhul vÔib sama summat kulutada mitu korda.
4. PĂŒsivus
Ma tegin katseid konteineri jĂ€rsu vĂ€ljalĂŒlitamisega lĂ€bi
docker kill my-irisAndmebaas talus seda hÀsti. Probleeme ei tuvastatud.
KokkuvÔte
InterSystems IRIS'is on globaalsed tehingute tugi. Need on tÔeliselt atomaarset ja usaldusvÀÀrset. Andmebaasi jÀrjepidevuse tagamiseks globaalses keskkonnas on arendaja pingutused ning tehingute kasutamine vajalik, kuna keerulised sisseehitatud konstruktsioonid, nagu vÀlised vÔtmed, puuduvad.
Globaalide eraldusaste ilma lukustusteta on READ UNCOMMITTED, ja lukustuste kasutamise korral saab tagada isegi SERIALIZE taseme.
Globaalide tehingute Ôigsus ja kiirus sÔltuvad vÀga palju arendaja oskustest: mida laiemalt kasutatakse jagatud lukustusi lugemisel, seda kÔrgem on eraldatusetunne, ja mida kitsamad on eksklusiivsed lukustused, seda suurem on jÔudlus.
Allikas: habr.com
