Tapahtumat InterSystems IRIS Globalsissa

Tapahtumat InterSystems IRIS GlobalsissaInterSystems IRIS DBMS tukee mielenkiintoisia rakenteita tietojen tallentamiseen - globaaleja. Pohjimmiltaan nämä ovat monitasoisia avaimia, joissa on erilaisia ​​lisähyötyjä tapahtumien muodossa, nopeita toimintoja datapuiden läpikulkuun, lukot ja oma ObjectScript-kieli.

Lue lisää globaaleista artikkelisarjasta "Globalit ovat aarremiekkoja tietojen tallentamiseen":

puut. Osa 1
puut. Osa 2
Harvat taulukot. Osa 3

Kiinnostuin siitä, miten transaktiot toteutetaan globaaleilla, mitä ominaisuuksia siellä on. Loppujen lopuksi tämä on täysin erilainen tietojen tallennusrakenne kuin tavalliset taulukot. Paljon matalampi taso.

Kuten relaatiotietokantojen teoriasta tiedetään, transaktioiden hyvän toteutuksen tulee täyttää vaatimukset ACID:

A - Atomi (atomisiteetti). Kaikki tapahtumaan tehdyt muutokset tai ei mitään muutoksia kirjataan.

C - Johdonmukaisuus. Kun tapahtuma on valmis, tietokannan loogisen tilan on oltava sisäisesti johdonmukainen. Tämä vaatimus koskee monella tapaa ohjelmoijaa, mutta SQL-tietokantojen tapauksessa myös vierasavaimia.

I - Eristä. Rinnakkaiset tapahtumat eivät saa vaikuttaa toisiinsa.

D - Kestävä. Tapahtuman onnistuneen loppuun saattamisen jälkeen alemmilla tasoilla esiintyvien ongelmien (esimerkiksi sähkökatkos) ei pitäisi vaikuttaa tapahtuman muuttamiin tietoihin.

Globaalit ovat ei-relaatiotietorakenteita. Ne on suunniteltu toimimaan erittäin nopeasti erittäin rajoitetuilla laitteistoilla. Katsotaanpa transaktioiden toteutusta globaaleissa käyttäen virallinen IRIS-telakkakuva.

IRIS-tapahtumien tukemiseen käytetään seuraavia komentoja: TSTART, TCOMMIT, TROLLBACK.

1. Atomuus

Helpoin tapa tarkistaa on atomiteetti. Tarkistamme tietokantakonsolista.

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

Sitten päätämme:

Write ^a(1), “ ”, ^a(2), “ ”, ^a(3)

Saamme:

1 2 3

Kaikki on hyvin. Atomisuus säilyy: kaikki muutokset kirjataan.

Monimutkaistaan ​​tehtävää, esitellään virhe ja katsotaan kuinka tapahtuma tallennetaan, osittain tai ei ollenkaan.

Tarkistetaan vielä atomiteetti:

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

Sitten pysäytämme kontin väkisin, käynnistämme sen ja katsomme.

docker kill my-iris

Tämä komento vastaa lähes pakotettua sammutusta, koska se lähettää SIGKILL-signaalin pysäyttääkseen prosessin välittömästi.

Ehkä kauppa säästyi osittain?

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

- Ei, se ei ole säilynyt.

Kokeillaan palautuskomentoa:

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)

Mikään ei myöskään ole säilynyt.

2. Johdonmukaisuus

Koska globaleihin perustuvissa tietokannoissa avaimet tehdään myös globaaleille (muistutan, että globaali on alemman tason rakenne tietojen tallentamiseen kuin relaatiotaulukko), johdonmukaisuusvaatimuksen täyttämiseksi avaimeen tulee tehdä muutos. samassa liiketoimessa kuin muutos globaalissa.

Meillä on esimerkiksi globaali ^henkilö, johon tallennamme henkilöitä ja käytämme TIN-tunnusta avaimena.

^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
...

Tehdäksemme nopean haun suku- ja etunimen perusteella, teimme ^index-näppäimen.

^index(‘Kamenev’, ‘Sergey’, 1234567) = 1

Jotta tietokanta olisi johdonmukainen, meidän on lisättävä henkilö seuraavasti:

TSTART
^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
^index(‘Kamenev’, ‘Sergey’, 1234567) = 1
TCOMMIT

Vastaavasti, kun poistamme, meidän on käytettävä myös tapahtumaa:

TSTART
Kill ^person(1234567)
ZKill ^index(‘Kamenev’, ‘Sergey’, 1234567)
TCOMMIT

Toisin sanoen johdonmukaisuusvaatimuksen täyttäminen on täysin ohjelmoijan harteilla. Mutta mitä tulee globaaleihin, tämä on normaalia niiden matalan tason luonteen vuoksi.

3. Eristäminen

Tästä villit alkavat. Monet käyttäjät työskentelevät samanaikaisesti saman tietokannan parissa ja muuttavat samoja tietoja.

Tilanne on verrattavissa siihen, kun monet käyttäjät työskentelevät samanaikaisesti saman koodivaraston kanssa ja yrittävät samanaikaisesti tehdä muutoksia useisiin tiedostoihin kerralla.

Tietokannan pitäisi selvittää kaikki reaaliajassa. Ottaen huomioon, että vakavissa yrityksissä on jopa erityinen henkilö, joka on vastuussa versionhallinnasta (haarojen yhdistämisestä, ristiriitojen ratkaisemisesta jne.), ja tietokannan on tehtävä tämä kaikki reaaliajassa, tehtävän monimutkaisuus ja oikeellisuus. tietokannan suunnittelu ja sitä palveleva koodi.

Tietokanta ei ymmärrä käyttäjien tekemien toimien merkitystä ristiriitojen välttämiseksi, jos he työskentelevät samojen tietojen parissa. Se voi kumota vain yhden tapahtuman, joka on ristiriidassa toisen kanssa, tai suorittaa ne peräkkäin.

Toinen ongelma on, että tapahtuman suorittamisen aikana (ennen sitoutumista) tietokannan tila voi olla epäjohdonmukainen, joten on toivottavaa, että muut tapahtumat eivät pääse käsiksi tietokannan epäjohdonmukaiseen tilaan, mikä saavutetaan relaatiotietokannoissa. monin tavoin: tilannekuvien luominen, rivien moniversio jne.

Rinnakkaisten tapahtumien suorittamisessa on meille tärkeää, etteivät ne häiritse toisiaan. Tämä on eristäytymisen ominaisuus.

SQL määrittelee 4 eristystasoa:

  • LUE SITOUMATTOMASTI
  • LUE SITOUTUNUT
  • TOISTETTU LUE
  • SARJOITTAVA

Katsotaanpa jokaista tasoa erikseen. Kunkin tason toteutuskustannukset kasvavat lähes eksponentiaalisesti.

LUE SITOUMATTOMASTI - Tämä on alhaisin eristyksen taso, mutta samalla nopein. Tapahtumat voivat lukea toistensa tekemiä muutoksia.

LUE SITOUTUNUT on eristyksen seuraava taso, mikä on kompromissi. Tapahtumat eivät voi lukea toistensa muutoksia ennen sitoumusta, mutta ne voivat lukea sitoumuksen jälkeen tehdyt muutokset.

Jos meillä on pitkä tapahtuma T1, jonka aikana tapahtui sitoumuksia tapahtumissa T2, T3 ... Tn, jotka toimivat samoilla tiedoilla kuin T1, niin T1:ssä dataa pyydettäessä saadaan joka kerta eri tulos. Tätä ilmiötä kutsutaan ei-toistettavaksi lukemiseksi.

TOISTETTU LUE – tällä eristystasolla meillä ei ole ei-toistettavan lukemisen ilmiötä, koska jokaista tietojen lukupyyntöä varten luodaan tilannekuva tulostiedoista ja kun niitä käytetään uudelleen samassa tapahtumassa, tilannevedoksen tiedot käytetään. Phantom-dataa on kuitenkin mahdollista lukea tällä eristystasolla. Tämä viittaa uusien rivien lukemiseen, jotka on lisätty rinnakkaisilla sitoutuneilla tapahtumilla.

SARJOITTAVA — korkein eristystaso. Sille on ominaista se, että tapahtumassa millään tavalla käytetyt tiedot (lukeminen tai muuttaminen) tulevat muiden tapahtumien saataville vasta ensimmäisen tapahtuman suorittamisen jälkeen.

Selvitetään ensin, onko tapahtumassa toimintojen eristäminen pääsäikeestä. Avataan 2 pääteikkunaa.

Kill ^t

Write ^t(1)
2

TSTART
Set ^t(1)=2

Eristystä ei ole. Yksi säie näkee, mitä toinen tapahtuman avannut tekee.

Katsotaanpa, näkevätkö eri säikeiden tapahtumat, mitä niiden sisällä tapahtuu.

Avataan 2 pääteikkunaa ja 2 tapahtumaa rinnakkain.

kill ^t
TSTART
Write ^t(1)
3

TSTART
Set ^t(1)=3

Rinnakkaiset tapahtumat näkevät toistensa tiedot. Saimme siis yksinkertaisimman, mutta myös nopeimman eristystason, READ UN COMMITED.

Periaatteessa tätä voitaisiin odottaa globaaleilta tahoilta, joille suorituskyky on aina ollut prioriteetti.

Entä jos tarvitsemme korkeamman tason eristäytymistä globaaleilla toimissa?

Täällä sinun on pohdittava, miksi eristystasoja ylipäänsä tarvitaan ja miten ne toimivat.

Korkein eristystaso, SERIALIZE, tarkoittaa, että rinnakkain suoritettujen tapahtumien tulos vastaa niiden peräkkäistä toteutusta, mikä takaa yhteentörmäysten puuttumisen.

Voimme tehdä tämän käyttämällä ObjectScriptin älykkäitä lukkoja, joilla on paljon erilaisia ​​käyttötarkoituksia: voit tehdä säännöllisen, inkrementaalisen, usean lukituksen komennolla LOCK.

Alemmat eristystasot ovat kompromisseja, jotka on suunniteltu lisäämään tietokannan nopeutta.

Katsotaanpa, kuinka voimme saavuttaa erilaisia ​​eristystasoja lukkojen avulla.

Tämän operaattorin avulla voit ottaa paitsi eksklusiivisia lukkoja, joita tarvitaan tietojen vaihtamiseen, myös niin kutsuttuja jaettuja lukoja, jotka voivat viedä useita säikeitä rinnakkain, kun niiden on luettava tietoja, joita muiden prosessien ei pitäisi muuttaa lukuprosessin aikana.

Lisätietoja kaksivaiheisesta estomenetelmästä venäjäksi ja englanniksi:

Kaksivaiheinen esto
Kaksivaiheinen lukitus

Vaikeus on, että tapahtuman aikana tietokannan tila voi olla epäjohdonmukainen, mutta tämä epäjohdonmukainen data näkyy muille prosesseille. Kuinka välttää tämä?

Luomme lukkojen avulla näkyvyysikkunoita, joissa tietokannan tila on johdonmukainen. Ja kaikkea pääsyä sellaisiin sovitun tilan näkyvyysikkunoihin valvotaan lukoilla.

Samojen tietojen jaetut lukot ovat uudelleenkäytettäviä – useat prosessit voivat viedä ne. Nämä lukot estävät muita prosesseja muuttamasta tietoja, esim. niitä käytetään muodostamaan johdonmukaisia ​​tietokantatilan ikkunoita.

Tietojen muuttamiseen käytetään eksklusiivisia lukkoja - vain yksi prosessi voi kestää tällaisen lukon. Ainutlaatuisen lukon voi ottaa:

  1. Mikä tahansa prosessi, jos tiedot ovat ilmaisia
  2. Vain prosessi, jolla on jaettu lukko näille tiedoille ja joka pyysi ensimmäisenä yksinomaista lukitusta.

Tapahtumat InterSystems IRIS Globalsissa

Mitä kapeampi näkyvyysikkuna on, sitä kauemmin muiden prosessien on odotettava sitä, mutta sitä johdonmukaisempi tietokannan tila siinä voi olla.

READ_COMMITTED - Tämän tason ydin on, että näemme vain sitoutuneita tietoja muista säikeistä. Jos toisen tapahtuman tietoja ei ole vielä sitoutunut, näemme sen vanhan version.

Näin voimme rinnastaa työn sen sijaan, että odotamme lukon vapautumista.

Ilman erikoistemppuja emme voi nähdä IRIS:ssä tiedoista vanhaa versiota, joten joudumme tyytymään lukoihin.

Tästä syystä meidän on käytettävä jaettuja lukkoja, jotta tiedot voidaan lukea vain johdonmukaisina hetkinä.

Oletetaan, että meillä on käyttäjäkunta ^henkilö, joka siirtää rahaa toisilleen.

Siirtymähetki henkilöltä 123 henkilölle 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)

Rahasumman pyytämiseen henkilöltä 123 ennen veloitusta on liitettävä eksklusiivinen lohko (oletuksena):

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

Ja jos sinun on näytettävä tilin tila henkilökohtaisella tililläsi, voit käyttää jaettua lukkoa tai olla käyttämättä sitä ollenkaan:

LOCK +^person(123)#”S”
Write ^person(123)

Jos kuitenkin oletetaan, että tietokantatoiminnot suoritetaan lähes välittömästi (muistutan, että globaalit ovat paljon alemman tason rakenne kuin relaatiotaulukko), tämän tason tarve vähenee.

TOISTETTU LUE - Tämä eristystaso mahdollistaa useiden tietojen lukemisen, joita voidaan muokata samanaikaisilla tapahtumilla.

Näin ollen meidän on asetettava jaettu lukitus muuttamiemme tietojen lukemiselle ja eksklusiiviset lukot muumille tiedoille.

Onneksi LOCK-operaattorin avulla voit listata yksityiskohtaisesti kaikki tarvittavat lukot, joita voi olla paljon, yhdellä lauseella.

LOCK +^person(123, amount)#”S”
чтение ^person(123, amount)

muut toiminnot (tällä hetkellä rinnakkaiset säikeet yrittävät muuttaa ^henkilö(123, summa), mutta eivät voi)

LOCK +^person(123, amount)
изменение ^person(123, amount)
LOCK -^person(123, amount)

чтение ^person(123, amount)
LOCK -^person(123, amount)#”S”

Kun luettelet lukot pilkuilla erotettuina, ne otetaan peräkkäin, mutta jos teet näin:

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

sitten ne otetaan atomisesti kaikki kerralla.

SARJALLISTAA — Meidän on asetettava lukot niin, että lopulta kaikki yhteistä dataa sisältävät tapahtumat suoritetaan peräkkäin. Tätä lähestymistapaa käytettäessä useimpien lukkojen tulisi olla yksinoikeudellisia, ja ne on suoritettava maailman pienimmillä alueilla.

Jos puhumme varojen veloituksesta globaalissa ^henkilössä, niin vain SERIALIZE-eristystaso on sille hyväksyttävä, koska rahat on käytettävä tiukasti peräkkäin, muuten on mahdollista kuluttaa sama määrä useita kertoja.

4. Kestävyys

Tein testejä säiliön kovaa leikkaamista käyttäen

docker kill my-iris

Pohja kesti niitä hyvin. Mitään ongelmia ei havaittu.

Johtopäätös

InterSystems IRIS tarjoaa maailmanlaajuisille tapahtumille tukea. Ne ovat todella atomisia ja luotettavia. Globaaleihin perustuvan tietokannan johdonmukaisuuden varmistamiseksi tarvitaan ohjelmoijien ponnisteluja ja tapahtumien käyttöä, koska siinä ei ole monimutkaisia ​​sisäänrakennettuja rakenteita, kuten vierasavaimia.

Globaalien eristystaso ilman lukkoja on READ UNCOMMITED, ja lukkoja käytettäessä se voidaan varmistaa SERIALIZE-tasoon asti.

Globaalien tapahtumien oikeellisuus ja nopeus riippuvat suuresti ohjelmoijan taidosta: mitä laajemmin jaettuja lukkoja käytetään lukemisessa, sitä korkeampi eristysaste ja mitä suppeammin poissulkevat lukot otetaan, sitä nopeampi suorituskyky.

Lähde: will.com

Lisää kommentti