Darījumi InterSystems IRIS globals

DarÄ«jumi InterSystems IRIS globalsInterSystems IRIS DBVS atbalsta interesantas datu glabāŔanas struktÅ«ras - globālos. BÅ«tÄ«bā tās ir daudzlÄ«meņu atslēgas ar dažādiem papildu labumiem transakciju veidā, ātrām funkcijām datu koku ŔķērsoÅ”anai, slēdzenes un savu ObjectScript valodu.

Vairāk par globāliem lasiet rakstu sērijā ā€œGlobāli ir dārgumu zobeni datu glabāŔanaiā€:

Koki. 1. daļa
Koki. 2. daļa
Reti masīvi. 3. daļa

Sāku interesēties, kā globalos tiek realizēti darÄ«jumi, kādas tur ir iespējas. Galu galā Ŕī ir pilnÄ«gi atŔķirÄ«ga datu glabāŔanas struktÅ«ra nekā parastās tabulas. Daudz zemāks lÄ«menis.

Kā zināms no relāciju datu bāzu teorijas, labai transakciju ievieŔanai ir jāatbilst prasībām ACID:

A - Atomiskais (atomiskums). Tiek reģistrētas visas darījumā veiktās izmaiņas vai tās nav vispār.

C ā€“ konsekvence. Pēc darÄ«juma pabeigÅ”anas datu bāzes loÄ£iskajam stāvoklim jābÅ«t iekŔēji konsekventam. Daudzējādā ziņā Ŕī prasÄ«ba attiecas uz programmētāju, bet SQL datu bāzu gadÄ«jumā tā attiecas arÄ« uz ārējām atslēgām.

Es - Izolēt. Paralēli veiktie darījumi nedrīkst ietekmēt viens otru.

D - IzturÄ«gs. Pēc veiksmÄ«gas darÄ«juma pabeigÅ”anas problēmām zemākos lÄ«meņos (piemēram, strāvas padeves pārtraukums) nevajadzētu ietekmēt datus, kas mainÄ«ti darÄ«juma rezultātā.

Globālie ir nerelāciju datu struktÅ«ras. Tie tika izstrādāti, lai darbotos Ä«paÅ”i ātri ar ļoti ierobežotu aparatÅ«ru. ApskatÄ«sim transakciju ievieÅ”anu globalos, izmantojot oficiālais IRIS dokera attēls.

Lai atbalstÄ«tu darÄ«jumus IRIS, tiek izmantotas Ŕādas komandas: TSTART, PASÅŖTÄŖT, TROLLBACK.

1. Atomiskums

VienkārŔākais veids, kā pārbaudÄ«t atomitāti. Mēs pārbaudām no datu bāzes konsoles.

Kill ^a
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TCOMMIT

Tad mēs secinām:

Write ^a(1), ā€œ ā€, ^a(2), ā€œ ā€, ^a(3)

Mēs iegūstam:

1 2 3

Viss ir kārtībā. Atomiskums tiek saglabāts: visas izmaiņas tiek reģistrētas.

Sarežģīsim uzdevumu, ievadīsim kļūdu un redzēsim, kā darījums tiek saglabāts daļēji vai vispār netiek saglabāts.

Vēlreiz pārbaudīsim atomitāti:

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3

Tad mēs ar spēku apturēsim konteineru, palaidīsim to un redzēsim.

docker kill my-iris

Å Ä« komanda ir gandrÄ«z lÄ«dzvērtÄ«ga piespiedu izslēgÅ”anai, jo tā nosÅ«ta SIGKILL signālu, lai nekavējoties apturētu procesu.

Varbūt darījums tika daļēji saglabāts?

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

- Nē, tas nav izdzīvojis.

Izmēģināsim atgrieÅ”anas komandu:

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TROLLBACK

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

Arī nekas nav saglabājies.

2. Konsekvence

Tā kā datu bāzēs, kuru pamatā ir globālās vērtÄ«bas, atslēgas tiek veidotas arÄ« uz globālajām (atgādināŔu, ka globālā ir zemāka lÄ«meņa struktÅ«ra datu glabāŔanai nekā relāciju tabula), lai izpildÄ«tu konsekvences prasÄ«bu, ir jāiekļauj atslēgas izmaiņas. tajā paŔā darÄ«jumā kā izmaiņas globālajā.

Piemēram, mums ir globāla ^persona, kurā mēs glabājam personības un kā atslēgu izmantojam TIN.

^person(1234567, ā€˜firstnameā€™) = ā€˜Sergeyā€™
^person(1234567, ā€˜lastnameā€™) = ā€˜Kamenevā€™
^person(1234567, ā€˜phoneā€™) = ā€˜+74995555555
...

Lai ātri meklētu pēc uzvārda un vārda, mēs izveidojām taustiņu ^index.

^index(ā€˜Kamenevā€™, ā€˜Sergeyā€™, 1234567) = 1

Lai datu bāze būtu konsekventa, persona jāpievieno Ŕādi:

TSTART
^person(1234567, ā€˜firstnameā€™) = ā€˜Sergeyā€™
^person(1234567, ā€˜lastnameā€™) = ā€˜Kamenevā€™
^person(1234567, ā€˜phoneā€™) = ā€˜+74995555555
^index(ā€˜Kamenevā€™, ā€˜Sergeyā€™, 1234567) = 1
TCOMMIT

AttiecÄ«gi, dzÄ“Å”ot, mums ir jāizmanto arÄ« darÄ«jums:

TSTART
Kill ^person(1234567)
ZKill ^index(ā€˜Kamenevā€™, ā€˜Sergeyā€™, 1234567)
TCOMMIT

Citiem vārdiem sakot, konsekvences prasības izpilde pilnībā gulstas uz programmētāja pleciem. Bet, runājot par globālajiem, tas ir normāli to zemā līmeņa dēļ.

3. Izolācija

Šeit sākas savvaļas dabas. Daudzi lietotāji vienlaikus strādā pie vienas datu bāzes, mainot vienus un tos paŔus datus.

Situācija ir salÄ«dzināma ar situāciju, kad daudzi lietotāji vienlaikus strādā ar vienu un to paÅ”u kodu krātuvi un mēģina vienlaikus veikt izmaiņas daudzos failos vienlaikus.

Datubāzei tas viss ir jāsakārto reāllaikā. Ņemot vērā, ka nopietnos uzņēmumos ir pat Ä«paÅ”s cilvēks, kas atbild par versiju kontroli (par filiāļu apvienoÅ”anu, konfliktu risināŔanu u.c.), un datu bāzei tas viss jādara reāllaikā, uzdevuma sarežģītÄ«ba un pareizÄ«ba. datu bāzes dizains un kods, kas to apkalpo.

Datubāze nevar saprast lietotāju veikto darbÄ«bu nozÄ«mi, lai izvairÄ«tos no konfliktiem, ja viņi strādā ar tiem paÅ”iem datiem. Tas var atsaukt tikai vienu darÄ«jumu, kas ir pretrunā ar citu, vai izpildÄ«t tos secÄ«gi.

Problēma ir arī tā, ka darījuma izpildes laikā (pirms commit) datu bāzes stāvoklis var būt nekonsekvents, tāpēc vēlams, lai citiem darījumiem nebūtu pieejams datu bāzes nekonsekventais stāvoklis, kas tiek panākts relāciju datu bāzēs. daudzos veidos: veidojot momentuzņēmumus, vairākas versijas rindas utt.

Veicot darÄ«jumus paralēli, mums ir svarÄ«gi, lai tie netraucētu viens otram. Å Ä« ir izolācijas Ä«paŔība.

SQL definē 4 izolācijas līmeņus:

  • LASI NEKĀRTOTI
  • LASÄŖT SAISTÄŖTU
  • ATKĀRTOTI LASÄŖJUMS
  • SERIALIZĒJAMS

ApskatÄ«sim katru lÄ«meni atseviŔķi. Katra lÄ«meņa ievieÅ”anas izmaksas pieaug gandrÄ«z eksponenciāli.

LASI NEKĀRTOTI - tas ir zemākais izolācijas lÄ«menis, bet tajā paŔā laikā ātrākais. DarÄ«jumos var lasÄ«t viens otra veiktās izmaiņas.

LASÄŖT SAISTÄŖTU ir nākamais izolācijas lÄ«menis, kas ir kompromiss. DarÄ«jumi nevar nolasÄ«t viens otra izmaiņas pirms saistÄ«bu izpildes, taču tās var lasÄ«t visas izmaiņas, kas veiktas pēc saistÄ«bu izpildes.

Ja mums ir ilgs darÄ«jums T1, kura laikā notika commits darÄ«jumos T2, T3 ... Tn, kas strādāja ar tiem paÅ”iem datiem kā T1, tad pieprasot datus T1, mēs katru reizi iegÅ«sim citu rezultātu. Å o parādÄ«bu sauc par neatkārtojamu lasÄ«Å”anu.

ATKĀRTOTI LASÄŖJUMS ā€” Å”ajā izolācijas lÄ«menÄ« mums nav neatkārtojamas nolasÄ«Å”anas fenomena, jo katram datu nolasÄ«Å”anas pieprasÄ«jumam tiek izveidots rezultāta datu momentuzņēmums un, atkārtoti izmantojot tajā paŔā darÄ«jumā, momentuzņēmuma dati. tiek izmantots. Tomēr Å”ajā izolācijas lÄ«menÄ« ir iespējams nolasÄ«t fantoma datus. Tas attiecas uz jaunu rindu nolasÄ«Å”anu, kas tika pievienotas paralēli veikto darÄ«jumu rezultātā.

SERIALIZĒJAMS ā€” visaugstākais izolācijas lÄ«menis. To raksturo fakts, ka dati, kas jebkādā veidā tiek izmantoti darÄ«jumā (nolasot vai mainot), kļūst pieejami citiem darÄ«jumiem tikai pēc pirmā darÄ«juma pabeigÅ”anas.

Vispirms noskaidrosim, vai darījuma operācijas ir izolētas no galvenā pavediena. Atvērsim 2 termināļa logus.

Kill ^t

Write ^t(1)
2

TSTART
Set ^t(1)=2

Nav izolācijas. Viens pavediens redz, ko dara otrs, kurÅ” atvēra darÄ«jumu.

Paskatīsimies, vai dažādu pavedienu darījumi redz, kas notiek tajos.

Atvērsim 2 termināļa logus un paralēli atvērsim 2 darījumus.

kill ^t
TSTART
Write ^t(1)
3

TSTART
Set ^t(1)=3

Paralēli darÄ«jumi redz viens otra datus. Tātad, mēs ieguvām vienkārŔāko, bet arÄ« ātrāko izolācijas lÄ«meni, READ UNCOMMITED.

Principā to varētu sagaidīt globālajiem uzņēmumiem, kuriem sniegums vienmēr ir bijis prioritāte.

Ko darīt, ja mums ir nepiecieŔams augstāks izolācijas līmenis operācijās ar globālajiem objektiem?

Å eit jums ir jādomā par to, kāpēc izolācijas lÄ«meņi vispār ir nepiecieÅ”ami un kā tie darbojas.

Augstākais izolācijas līmenis SERIALIZE nozīmē, ka paralēli veikto darījumu rezultāts ir līdzvērtīgs to secīgajai izpildei, kas garantē sadursmju neesamību.

Mēs to varam izdarÄ«t, izmantojot viedās slēdzenes ObjectScript, kurām ir daudz dažādu lietojumu: jÅ«s varat veikt regulāru, pakāpenisku, vairāku bloÄ·Ä“Å”anu ar komandu LOCK.

Zemāks izolācijas lÄ«menis ir kompromiss, kas paredzēts datu bāzes ātruma palielināŔanai.

Apskatīsim, kā mēs varam sasniegt dažādus izolācijas līmeņus, izmantojot slēdzenes.

Å is operators ļauj paņemt ne tikai ekskluzÄ«vas datu maiņai nepiecieÅ”amās slēdzenes, bet arÄ« tā sauktās koplietotās slēdzenes, kas paralēli var aizņemt vairākus pavedienus, kad tiem nepiecieÅ”ams nolasÄ«t datus, kurus lasÄ«Å”anas procesā nevajadzētu mainÄ«t citiem procesiem.

PlaŔāka informācija par divfāžu bloÄ·Ä“Å”anas metodi krievu un angļu valodā:

ā†’ Divfāžu bloÄ·Ä“Å”ana
ā†’ Divfāžu bloÄ·Ä“Å”ana

Grūtības ir tādas, ka darījuma laikā datu bāzes stāvoklis var būt nekonsekvents, bet Ŕie nekonsekventie dati ir redzami citiem procesiem. Kā no tā izvairīties?

Izmantojot slēdzenes, mēs izveidosim redzamÄ«bas logus, kuros datu bāzes stāvoklis bÅ«s konsekvents. Un visa pieeja Ŕādiem norunātā stāvokļa redzamÄ«bas logiem tiks kontrolēta ar slēdzenēm.

Vienu un to paÅ”u datu koplietotās slēdzenes ir atkārtoti izmantojamas ā€” tos var izmantot vairāki procesi. Å Ä«s slēdzenes neļauj citiem procesiem mainÄ«t datus, t.i. tos izmanto konsekventa datu bāzes stāvokļa logu veidoÅ”anai.

Datu izmaiņām tiek izmantotas ekskluzÄ«vas slēdzenes ā€“ Ŕādu bloÄ·Ä“Å”anu var veikt tikai viens process. EkskluzÄ«vu slēdzeni var paņemt:

  1. JebkurÅ” process, ja dati ir bezmaksas
  2. Tikai process, kuram ir koplietota bloķēŔana Ŕiem datiem un kurŔ pirmais pieprasīja ekskluzīvu bloķēŔanu.

Darījumi InterSystems IRIS globals

Jo Ŕaurāks ir redzamības logs, jo ilgāk citiem procesiem tas jāgaida, bet jo konsekventāks var būt datu bāzes stāvoklis tajā.

READ_COMMITTED ā€” Ŕī lÄ«meņa bÅ«tÄ«ba ir tāda, ka mēs redzam tikai iegÅ«tos datus no citiem pavedieniem. Ja dati citā darÄ«jumā vēl nav piesaistÄ«ti, mēs redzam tā veco versiju.

Tas ļauj mums paralēli veikt darbu, nevis gaidÄ«t slēdzenes atbrÄ«voÅ”anu.

Bez Ä«paÅ”iem trikiem IRIS nevarēsim redzēt veco datu versiju, tāpēc nāksies iztikt ar slēdzenēm.

AttiecÄ«gi mums bÅ«s jāizmanto koplietotās bloÄ·Ä“Å”anas, lai datus varētu nolasÄ«t tikai konsekvences brīžos.

Pieņemsim, ka mums ir lietotāju bāze ^persona, kas pārskaita naudu viens otram.

Pārejas brīdis no personas 123 uz personu 242:

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)

Naudas summas pieprasÄ«Å”anas brÄ«dim no personas 123 pirms norakstÄ«Å”anas jāpievieno ekskluzÄ«vs bloks (pēc noklusējuma):

LOCK +^person(123)
Write ^person(123)

Un, ja jums ir jāparāda konta statuss savā personīgajā kontā, varat izmantot koplietojamo slēdzeni vai to neizmantot vispār:

LOCK +^person(123)#ā€Sā€
Write ^person(123)

Taču, ja pieņemam, ka datubāzes darbÄ«bas tiek veiktas gandrÄ«z acumirklÄ« (atgādināŔu, ka globālie ir daudz zemāka lÄ«meņa struktÅ«ra nekā relāciju tabula), tad nepiecieÅ”amÄ«ba pēc Ŕī lÄ«meņa samazinās.

ATKĀRTOTI LASÄŖJUMS - Å is izolācijas lÄ«menis ļauj vairākkārt nolasÄ«t datus, kurus var mainÄ«t, veicot vienlaikus darÄ«jumus.

AttiecÄ«gi mums bÅ«s jābloķē mainÄ«to datu lasÄ«Å”ana un ekskluzÄ«vas bloÄ·Ä“Å”anas iespējas datiem, kurus mēs mainām.

Par laimi, LOCK operators ļauj detalizēti uzskaitÄ«t visas nepiecieÅ”amās slēdzenes, kuru var bÅ«t ļoti daudz, vienā paziņojumā.

LOCK +^person(123, amount)#ā€Sā€
чтŠµŠ½ŠøŠµ ^person(123, amount)

citas darbÄ«bas (Å”obrÄ«d paralēlie pavedieni mēģina mainÄ«t ^person(123, summa), bet nevar)

LOCK +^person(123, amount)
ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŠµ ^person(123, amount)
LOCK -^person(123, amount)

чтŠµŠ½ŠøŠµ ^person(123, amount)
LOCK -^person(123, amount)#ā€Sā€

Uzskaitot slēdzenes, kas atdalītas ar komatiem, tās tiek ņemtas secīgi, bet, ja to darāt:

LOCK +(^person(123),^person(242))

tad tos ņem atomiski visus uzreiz.

SERIALIZĒT ā€” mums bÅ«s jāiestata bloÄ·Ä“Å”ana, lai galu galā visas transakcijas, kurām ir kopÄ«gi dati, tiktu izpildÄ«tas secÄ«gi. Lai izmantotu Å”o pieeju, lielākajai daļai slēdzeņu ir jābÅ«t ekskluzÄ«vām un veiktspējas nodroÅ”ināŔanai tās jāizmanto vismazākajās pasaules vietās.

Ja runājam par lÄ«dzekļu norakstÄ«Å”anu globālajā cilvēkā, tad tam ir pieņemams tikai SERIALIZE izolācijas lÄ«menis, jo nauda jātērē stingri secÄ«gi, pretējā gadÄ«jumā vienu un to paÅ”u summu iespējams iztērēt vairākas reizes.

4. Izturība

Es veicu testus ar cietu konteinera grieŔanu, izmantojot

docker kill my-iris

Bāze tos labi panesa. Problēmas netika konstatētas.

Secinājums

Globālajiem klientiem InterSystems IRIS ir transakciju atbalsts. Tie ir patiesi atomiski un uzticami. Lai nodroÅ”inātu uz globāliem datiem balstÄ«tas datubāzes konsekvenci, ir nepiecieÅ”amas programmētāja pÅ«les un transakciju izmantoÅ”ana, jo tai nav sarežģītu iebÅ«vētu konstrukciju, piemēram, ārējās atslēgas.

Globālu izolācijas lÄ«menis, neizmantojot slēdzenes, ir READ UNCOMMITED, un, izmantojot slēdzenes, to var nodroÅ”ināt lÄ«dz SERIALIZE lÄ«menim.

Globālos transakciju pareizÄ«ba un ātrums lielā mērā ir atkarÄ«gs no programmētāja prasmes: jo plaŔāk tiek izmantotas lasÄ«Å”anas laikā koplietotās slēdzenes, jo augstāks ir izolācijas lÄ«menis un jo Å”aurāk tiek ņemtas ekskluzÄ«vas slēdzenes, jo ātrāka ir veiktspēja.

Avots: www.habr.com

Pievieno komentāru