InterSystems IRIS глобалдык транзакциялар

InterSystems IRIS глобалдык транзакцияларInterSystems IRIS DBMS маалыматтарды сактоо үчүн кызыктуу структураларды колдойт - глобалдык. Негизи булар транзакциялар түрүндөгү ар кандай кошумча жакшы нерселери бар көп деңгээлдүү ачкычтар, маалымат дарактарын басып өтүү үчүн тез функциялар, кулпулар жана өзүнүн ObjectScript тили.

Глобалдар жөнүндө кененирээк "Глобалдар маалыматтарды сактоо үчүн кенч кылычтар" деген макалалар сериясынан окуңуз:

Дарактар. 1-бөлүк
Дарактар. 2-бөлүк
Сейрек массивдер. 3-бөлүк

Мен глобалдык масштабда транзакциялар кандай ишке ашат, кандай өзгөчөлүктөр бар деген суроолорго кызыктым. Анткени, бул кадимки таблицаларга караганда маалыматтарды сактоо үчүн таптакыр башка түзүлүш. Бир топ төмөн деңгээл.

Реляциялык маалымат базаларынын теориясынан белгилүү болгондой, транзакцияларды жакшы ишке ашыруу талаптарга жооп бериши керек КЫЧКЫЛ:

A - Атомдук (атомдук). Транзакцияга киргизилген бардык өзгөртүүлөр же такыр эч ким жазылбайт.

C - ырааттуулук. Транзакция аяктагандан кийин, маалымат базасынын логикалык абалы ички ырааттуу болушу керек. Көп жагынан бул талап программистке тиешелүү, бирок SQL маалымат базаларында чет өлкөлүк ачкычтарга да тиешелүү.

Мен - изоляция. Параллелдүү болгон транзакциялар бири-бирине таасирин тийгизбеши керек.

D - Туруктуу. Транзакция ийгиликтүү аяктагандан кийин, төмөнкү деңгээлдеги көйгөйлөр (мисалы, электр энергиясын өчүрүү) транзакция менен өзгөртүлгөн маалыматтарга таасирин тийгизбеши керек.

Глобалдар байланыштуу эмес маалымат структуралары. Алар өтө чектелген жабдыкта супер ылдам иштөө үчүн иштелип чыккан. Келгиле, глобалдык транзакцияларды колдонууну карап көрөлү расмий IRIS докер сүрөтү.

IRISде транзакцияларды колдоо үчүн төмөнкү буйруктар колдонулат: TSTART, TCOMMIT, ТРОЛЛБЕК.

1. Атомдук

Текшерүүнүн эң оңой жолу - атомизм. Биз маалымат базасынын консолунан текшеребиз.

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

Анда биз жыйынтык чыгарабыз:

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

Биз алабыз:

1 2 3

Баары жайында. Атомдуулук сакталып турат: бардык өзгөрүүлөр жазылат.

Келгиле, тапшырманы татаалдаштырып, ката киргизип, транзакциянын жарым-жартылай же такыр сакталышын көрөлү.

Келгиле, атомдуулугун дагы бир жолу текшерип көрөлү:

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

Анан контейнерди күч менен токтотуп, ишке киргизип, көрөбүз.

docker kill my-iris

Бул буйрук күч менен өчүрүүгө дээрлик барабар, анткени ал процессти дароо токтотуу үчүн SIGKILL сигналын жөнөтөт.

Балким, транзакция жарым-жартылай сакталып калганбы?

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

- Жок, аман калган жок.

Келгиле, артка кайтаруу буйругун колдонуп көрөлү:

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)

Эч нерсе да аман калган жок.

2. ырааттуулук

Глобалдык базаларга негизделген маалымат базаларында ачкычтар глобалдууларда да жасалгандыктан (эске сала кетейин, глобалдык - бул реляциялык таблицага караганда маалыматтарды сактоо үчүн төмөнкү деңгээлдеги структура), ырааттуулук талабын канааттандыруу үчүн, ачкычтын өзгөрүшү киргизилиши керек. глобалдык өзгөрүү сыяктуу эле бүтүмдө.

Мисалы, бизде глобалдуу адам бар, анда биз инсандарды сактайбыз жана биз ТИНди ачкыч катары колдонобуз.

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

Фамилиясы жана аты боюнча тез издөө үчүн, биз ^ индекс ачкычын жасадык.

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

Маалымат базасы ырааттуу болушу үчүн, биз төмөнкүдөй персонаны кошушубуз керек:

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

Демек, жок кылууда биз транзакцияны да колдонушубуз керек:

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

Башкача айтканда, ырааттуулук талабын аткаруу толугу менен программисттин мойнуна жүктөлөт. Бирок, глобалдык деңгээлге келгенде, бул алардын төмөнкү деңгээлдеги мүнөзүнө байланыштуу нормалдуу көрүнүш.

3. Изоляция

Жапайылар ушул жерден башталат. Көптөгөн колдонуучулар бир эле учурда бир эле маалымат базасында иштешет, ошол эле маалыматтарды өзгөртүшөт.

Кырдаал көптөгөн колдонуучулар бир эле учурда бир эле код репозиторийинде иштеп, бир эле учурда бир эле учурда көптөгөн файлдарга өзгөртүүлөрдү киргизүүгө аракет кылгандагы менен салыштырууга болот.

Маалымат базасы мунун бардыгын реалдуу убакыт режиминде иргеп алышы керек. Олуттуу компанияларда версияны башкаруу үчүн (бутактарды бириктирүү, чыр-чатактарды чечүү ж.б.у.с.) үчүн жооптуу атайын адам бар экенин эске алсак, маалымат базасы мунун баарын реалдуу убакытта, тапшырманын татаалдыгын жана тууралыгын аткарууга тийиш. маалымат базасынын дизайны жана аны тейлеген код.

Маалыматтар базасы, эгерде алар бир эле маалыматтар боюнча иштеп жаткан болсо, конфликттерди болтурбоо үчүн колдонуучулар жасаган аракеттердин маанисин түшүнө албайт. Ал башкасына карама-каршы келген бир транзакцияны гана жокко чыгара алат же аларды ырааттуу түрдө аткара алат.

Дагы бир көйгөй, транзакцияны аткаруу учурунда (милдеттенмеге чейин) маалымат базасынын абалы шайкеш келбей калышы мүмкүн, ошондуктан реляциялык маалымат базаларында жетишилген маалыматтар базасынын ыраатсыз абалына башка транзакциялардын кирүү мүмкүнчүлүгү жок болушу керек. ар кандай жолдор менен: көз ирмемдерди түзүү, көп версия саптарды ж.б.

Транзакцияларды параллелдүү жүргүзүүдө биз үчүн алардын бири-бирине тоскоол болбошу маанилүү. Бул изоляциянын касиети.

SQL 4 изоляция деңгээлин аныктайт:

  • МИЛДЕТТЕНБЕЙ ОКУ
  • ОКУУ КЕРЕК
  • КАЙТАЛАНГАН ОКУУ
  • СЕРИЯЛАШТЫРУУЧУ

Келгиле, ар бир деңгээлди өзүнчө карап көрөлү. Ар бир деңгээлди ишке ашырууга кеткен чыгымдар дээрлик экспоненциалдуу өсөт.

МИЛДЕТТЕНБЕЙ ОКУ - бул изоляциянын эң төмөнкү деңгээли, бирок ошол эле учурда эң ылдам. Транзакциялар бири-бирине киргизилген өзгөртүүлөрдү окуй алат.

ОКУУ КЕРЕК обочолонуунун кийинки деңгээли болуп саналат, бул компромисс болуп саналат. Транзакциялар милдеттенмеге чейин бири-биринин өзгөртүүлөрүн окуй алышпайт, бирок алар милдеттенмеден кийин жасалган бардык өзгөртүүлөрдү окуй алышат.

Эгерде бизде T1 транзакциялары T2, T3 ... Tn транзакцияларында орун алган, T1 сыяктуу маалыматтар менен иштеген узак транзакцияга ээ болсок, анда T1де маалыматтарды сураганда биз ар бир жолу башка жыйынтыкка ээ болобуз. Бул көрүнүш кайталанбаган окуу деп аталат.

КАЙТАЛАНГАН ОКУУ — бул обочолонуу деңгээлинде бизде кайталанбоочу окуу феномени жок, анткени маалыматтарды окууга болгон ар бир сурам үчүн жыйынтык маалыматтарынын сүрөтү түзүлөт жана ошол эле транзакцияда кайра колдонулганда, снапшоттун маалыматтары түзүлөт. колдонулат. Бирок, бул изоляция деңгээлинде фантомдук маалыматтарды окууга болот. Бул параллелдүү жасалган транзакциялар менен кошулган жаңы саптарды окууну билдирет.

СЕРИЯЛАШТЫРУУЧУ — изоляциянын эң жогорку деңгээли. Бул транзакцияда (окуу же өзгөртүү) кандайдыр бир жол менен колдонулган маалыматтар биринчи транзакция аяктагандан кийин гана башка транзакциялар үчүн жеткиликтүү болушу менен мүнөздөлөт.

Биринчиден, келгиле, транзакцияда операциялардын негизги жиптен обочолонуу бар же жок экенин аныктап көрөлү. Келгиле, 2 терминал терезесин ачалы.

Kill ^t

Write ^t(1)
2

TSTART
Set ^t(1)=2

Эч кандай изоляция жок. Бир жип транзакцияны ачкан экинчиси эмне кылып жатканын көрөт.

Келгиле, ар кандай жиптердеги транзакциялар алардын ичинде эмне болуп жатканын көрөбү.

Келгиле, 2 терминал терезесин ачып, параллелдүү 2 транзакция ачалы.

kill ^t
TSTART
Write ^t(1)
3

TSTART
Set ^t(1)=3

Параллель транзакциялар бири-биринин маалыматтарын көрөт. Ошентип, биз эң жөнөкөй, бирок эң ылдам изоляция деңгээлин алдык, READ UNCOMMITED.

Негизи, муну глобалдуу адамдар үчүн күтсө болот, алар үчүн аткаруу дайыма артыкчылыктуу болуп келген.

Эгер глобалдык операцияларда көбүрөөк обочолонуу керек болсочы?

Бул жерде сиз изоляция деңгээли эмне үчүн керек жана алар кандай иштеши жөнүндө ойлонушуңуз керек.

Эң жогорку обочолонуу деңгээли, SERIALIZE, параллелдүү аткарылган транзакциялардын натыйжасы алардын ырааттуу аткарылышына барабар экенин билдирет, бул коллизиялардын болбошуна кепилдик берет.

Биз муну ObjectScript'теги акылдуу кулпулардын жардамы менен жасай алабыз, алардын ар кандай түрлөрү бар: сиз буйрук менен үзгүлтүксүз, кошумча, бир нече кулпулоону жасай аласыз. LOCK.

Төмөнкү изоляция деңгээли маалымат базасынын ылдамдыгын жогорулатууга багытталган.

Келгиле, кулпуларды колдонуу менен обочолонуунун ар кандай деңгээлине кантип жетсек болорун карап көрөлү.

Бул оператор маалыматтарды өзгөртүү үчүн зарыл болгон эксклюзивдүү кулпуларды гана эмес, окуу процессинде башка процесстер тарабынан өзгөртүлбөшү керек болгон маалыматтарды окуу керек болгондо параллелдүү бир нече жиптерди ала турган жалпы кулпуларды алууга мүмкүндүк берет.

Орус жана англис тилдеринде эки фазалуу бөгөттөө ыкмасы жөнүндө көбүрөөк маалымат:

Эки фазалуу блокировка
Эки фазалуу блокировка

Кыйынчылык - транзакция учурунда маалымат базасынын абалы шайкеш келбей калышы мүмкүн, бирок бул дал келбеген маалыматтар башка процесстерге көрүнүп турат. Муну кантип болтурбоо керек?

Кулпуларды колдонуу менен биз маалымат базасынын абалы ырааттуу боло турган көрүнүү терезелерин түзөбүз. Ал эми макулдашылган мамлекеттин көрүнүшүнүн мындай терезелерине бардык кирүү кулпулар менен башкарылат.

Бир эле дайындардын жалпы кулпулары кайра колдонууга болот — бир нече процесс аларды талап кылышы мүмкүн. Бул кулпулар башка процесстерге маалыматтарды өзгөртүүгө жол бербейт, б.а. алар ырааттуу маалымат базасынын абалынын терезелерин түзүү үчүн колдонулат.

Маалыматтарды өзгөртүү үчүн эксклюзивдүү кулпулар колдонулат - мындай кулпуну бир гана процесс ала алат. Эксклюзивдүү кулпу төмөнкүлөр тарабынан алынышы мүмкүн:

  1. Маалыматтар бекер болсо, ар кандай процесс
  2. Бул маалыматтарда жалпы кулпу бар жана эксклюзивдүү кулпусун биринчилерден болуп сураган процесс гана.

InterSystems IRIS глобалдык транзакциялар

Көрүнүү терезеси канчалык тар болсо, башка процесстер ошончолук көп убакыт күтүшү керек, бирок андагы маалымат базасынын абалы ошончолук ырааттуу болушу мүмкүн.

READ_COMMITTED — бул деңгээлдин маңызы биз башка жиптерден жасалган маалыматтарды гана көрөбүз. Эгерде башка транзакциядагы маалыматтар жасала элек болсо, анда биз анын эски версиясын көрөбүз.

Бул кулпу бошотулушун күтпөстөн, ишти параллелдештирүүгө мүмкүндүк берет.

Атайын трюктарсыз биз IRISдеги маалыматтардын эски версиясын көрө албайбыз, андыктан кулпулар менен жетишүүгө туура келет.

Демек, биз маалыматтарды ырааттуу учурда гана окууга уруксат берүү үчүн жалпы кулпуларды колдонушубуз керек.

Бизде бири-бирине акча которгон колдонуучу базасы бар дейли.

123-адамдан 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)

Дебеттөө алдында 123 адамдан акчанын суммасын суроо учуру эксклюзивдүү блок менен коштолууга тийиш (демейки боюнча):

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

Эгер сиз жеке аккаунтуңузда аккаунттун статусун көрсөтүшүңүз керек болсо, анда сиз жалпы кулпуну колдонсоңуз болот же аны такыр колдонбоңуз:

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

Бирок, эгерде биз маалымат базасы операциялары дээрлик бир заматта аткарылат деп ойлосок (глобалдар реляциялык таблицага караганда бир топ төмөн деңгээлдеги структура экенин эске сала кетейин), анда бул деңгээлге болгон муктаждык азаят.

КАЙТАЛАНГАН ОКУУ - Бул обочолонуу деңгээли бир эле учурда транзакциялар менен өзгөртүлүшү мүмкүн болгон маалыматтарды бир нече окууга мүмкүндүк берет.

Демек, биз өзгөрткөн маалыматтарды окууга жалпы кулпу жана биз өзгөрткөн маалыматтарга эксклюзивдүү кулпуларды коюуга туура келет.

Бактыга жараша, LOCK оператору бир билдирүүдө көп болушу мүмкүн болгон бардык керектүү кулпуларды майда-чүйдөсүнө чейин келтирүүгө мүмкүндүк берет.

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

башка операциялар (учурда параллелдүү жиптер ^person(123, сумма) өзгөртүүгө аракет кылат, бирок мүмкүн эмес)

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

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

Үтүр менен бөлүнгөн кулпуларды тизмелөөдө алар ырааттуу түрдө алынат, бирок муну кылсаңыз:

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

анда алар бир эле учурда атомдук жактан алынат.

СЕРИЯЛАШТЫРУУ — акыры жалпы маалыматтарга ээ болгон бардык транзакциялар ырааттуу түрдө аткарылышы үчүн кулпуларды орнотууга туура келет. Бул ыкма үчүн, көпчүлүк кулпулар эксклюзивдүү болушу керек жана аткаруу үчүн глобалдык эң кичинекей аймактарда кабыл алынышы керек.

Эгерде биз глобалдык ^адамда каражаттарды эсептен чыгаруу жөнүндө айта турган болсок, анда ал үчүн SERIALIZE обочолонуу деңгээли гана алгылыктуу, анткени акчаны ырааттуу түрдө жумшаш керек, антпесе бир эле сумманы бир нече жолу сарптоого болот.

4. Узактыгы

Мен контейнерди катуу кесүү менен сыноолорду өткөрдүм

docker kill my-iris

База аларга жакшы чыдаган. Эч кандай көйгөйлөр аныкталган жок.

жыйынтыктоо

Глобалдуулар үчүн, InterSystems IRIS транзакцияны колдойт. Алар чындап атомдук жана ишенимдүү. Глобалдык базанын ырааттуулугун камсыз кылуу үчүн программисттин аракети жана транзакцияларды колдонуу талап кылынат, анткени анда чет өлкөлүк ачкычтар сыяктуу татаал орнотулган конструкциялар жок.

Кулпуларды колдонбостон глобалдык обочолонуу деңгээли READ UNCOMMITED болуп саналат, ал эми кулпуларды колдонууда аны SERIALIZE деңгээлине чейин камсыз кылууга болот.

Глобалдардагы транзакциялардын тууралыгы жана ылдамдыгы программисттин чеберчилигинен көз каранды: окууда кеңири бөлүштүрүлгөн кулпулар канчалык көп колдонулса, обочолонуунун деңгээли ошончолук жогору болот жана канчалык тар эксклюзивдүү кулпулар алынса, аткаруу ошончолук тез болот.

Source: www.habr.com

Комментарий кошуу