Транзакцыі і механізмы іх кантролю

Транзакцыі

Транзакцыяй называецца паслядоўнасць аперацый над дадзенымі якая мае пачатак і канец

Транзакцыя гэта паслядоўнае выкананне аперацый чытання і запісы. Заканчэннем транзакцыі можа быць альбо захаванне змен (фіксацыя, commit) альбо адмена змен (адкат, rollback). У дачыненні да БД транзакцыя гэта некалькі запытаў, якія тлумачацца як адзіны запыт.

Транзакцыі павінны задавальняць уласцівасцям ACID

Атамарнасць. Транзакцыя або выконваецца поўнасцю або не выконваецца зусім.

Узгодненасць. Пры завяршэнні транзакцыі не павінны быць парушаны абмежаванні накладваюцца на дадзеныя (напрыклад constraints ў БД). Узгодненасць мае на ўвазе, што сістэма будзе пераведзена з аднаго карэктнага стану ў іншы карэктны.

Ізаляванасць. Паралельна выкананыя транзакцыі не павінны ўплываць сябар на сябра, напрыклад змяняць дадзеныя якія выкарыстоўвае іншая транзакцыя. Вынік выканання паралельных транзакцый павінен быць такім, як калі б транзакцыі выконваліся паслядоўна.

Устойлівасць. Пасля фіксацыі змены не павінны быць згублены.

Часопіс транзакцый

Часопіс захоўвае змены выкананыя транзакцыямі, забяспечвае атамарнасць і ўстойлівасць дадзеных у выпадку збою сістэмы.

Часопіс змяшчае значэнні, якія дадзеныя мелі да і пасля іх змены транзакцыяй. Write-ahead log strategy абавязвае дадаваць у часопіс запіс аб папярэдніх значэннях да пачатку, а аб канчатковых пасля завяршэння транзакцыі. У выпадку раптоўнага спынення сістэмы БД чытае лог у зваротным парадку і адмяняе змены зробленыя транзакцыямі. Сустрэўшы перапыненую транзакцыю БД выконвае яе і ўносіць змены аб ёй у часопіс. Знаходзячыся ў стане на момант збою, БД чытае лог у прамым парадку і вяртае змены зробленыя транзакцыямі. Такім чынам захоўваецца ўстойлівасць транзакцый, якія ўжо былі зафіксаваны і атамарнасць перарванай транзакцыі.

Простае паўторнае выкананне памылковых транзакцый недастаткова для аднаўлення.

Прыклад. На рахунку ў карыстача 500$ і карыстач вырашае зняць іх праз банкамат. Выконваюцца дзве транзакцыі. Першая чытае значэнне балансу і калі на балансе дастаткова сродкаў выдае грошы карыстачу. Другая адымае з балансу патрэбную суму. Дапушчальны, адбыўся збой сістэмы і першая аперацыя не выканалася, а другая выканалася. У гэтым выпадку мы не можам паўторна выдаць грошы карыстачу без вяртання сістэмы ў першапачатковы стан са станоўчым балансам.

Узроўні ізаляцыі

Чытанне фіксаваных дадзеных (Read Committed)

Праблема бруднага чытання (Dirty Read) заключаецца ў тым, што транзакцыя можа прачытаць прамежкавы вынік працы іншай транзакцыі.

Прыклад. Пачатковае значэнне балансу 0 $. Т1 дадае да балансу 50 $. Т2 счытвае значэнне балансу (50 $). Т1 адмяняе змены і завяршаецца. T2 працягвае выкананне размяшчаючы няслушнымі дадзенымі аб балансе.

Рашэннем з'яўляецца чытанне фіксаваных дадзеных (Read Committed) забараняльнае чытаць дадзеныя, змененыя транзакцыяй. Калі транзакцыя A змяніла некаторы набор дадзеных, то транзакцыя B пры звароце за гэтымі дадзенымі змушана чакаць завяршэнні транзакцыі A.

Паўтаранае чытанне (Repeatable Read)

Праблема страчаных змен (Lost Updates). Т1 захоўвае змены па-над зменамі Т2.

Прыклад. Пачатковае значэнне балансу 0 $ і дзве транзакцыі адначасова папаўняюць баланс. T1 і T2 чытаюць баланс роўны 0 $. Затым T2 дадае 200 $ да 0 $ і захоўвае вынік. T1 дадае 100$ да 0$ і захоўвае вынік. Выніковы вынік 100 $ замест 300 $.

Праблема непаўторнага чытання (Unrepeatable read). Паўторнае чытанне адных і тых жа дадзеных вяртае розныя значэнні.

Прыклад. Т1 чытае значэнне балансу роўнае 0 $. Затым Т2 дадае да балансу 50 $ і завяршаецца. Т1 паўторна чытае дадзеныя і выяўляе неадпаведнасць з папярэднім вынікам.

Паўтаранае чытанне (Repeatable Read) гарантуе што паўторнае чытанне верне той жа вынік. Даныя прачытаныя адной транзакцыяй забаронена мяняць у іншых да завяршэння транзакцыі. Калі транзакцыя A прачытала некаторы набор дадзеных, то транзакцыя B пры звароце за гэтымі дадзенымі змушаная чакаць завяршэнні транзакцыі A.

Спарадкаванае чытанне (Serializable)

Праблема фантомнага чытання (Phantom Reads). Два запыты абіралыя дадзеныя па нейкай умове вяртаюць розныя значэнні.

Прыклад. T1 запытвае колькасць усіх карыстальнікаў баланс якіх больш за 0$ але менш за 100$. T2 адымае 1 $ у карыстальніка з балансам 101 $. T1 паўторна выконвае запыт.

Спарадкаванае чытанне (Serializable). Транзакцыі выконваюцца як цалкам паслядоўныя. Забараняецца абнаўляць і дадаваць запісы, якія падпадаюць пад умовы запыту. Калі транзакцыя A запытала даныя ўсёй табліцы, то табліца цалкам замарожваецца для астатніх транзакцый да завяршэння транзакцыі A.

Планавальнік (Scheduler)

Усталёўвае чарговасць у якой павінны выконвацца аперацыі пры раўналежна якія праходзяць транзакцыях

Забяспечвае зададзены ўзровень ізаляванасці. Калі вынік выканання аперацый не залежыць ад іх чарговасці, то такія аперацыі камутатыўныя (Permutable). Камутатыўныя аперацыі чытання і аперацыі над рознымі дадзенымі. Аперацыі чытання-запісы і запісы-запісы не камутатыўныя. Задача планавальніка чаргаваць аперацыі выкананыя раўналежнымі транзакцыямі так, каб вынік выканання быў эквівалентны паслядоўнаму выкананню транзакцый.

Механізмы кантролю паралельных заданняў (Concurrency Control)

Аптымістычны заснаваны на выяўленні і дазволе канфліктаў, песімістычны на прадухіленні ўзнікнення канфліктаў

Пры аптымістычным падыходзе некалькі карыстачоў атрымліваюць у сваё распараджэнне копіі дадзеных. Першы які завяршыў рэдагаванне захоўвае змены, астатнія ж павінны ажыццявіць зліццё змен. Аптымістычны алгарытм дазваляе канфлікту адбыцца, але сістэма павінна аднавіцца пасля канфлікту.

Пры песімістычным падыходзе першы карыстач які захапіў дадзеныя перашкаджае атрыманню дадзеных астатнім. Калі канфлікты рэдкія разумна выбраць аптымістычную стратэгію, бо яна забяспечвае больш высокі ўзровень паралелізму.

Блакаванне (Locking)

Калі адна транзакцыя заблакавала дадзеныя, то астатнія транзакцыі пры звароце да дадзеных абавязаны чакаць разблакіроўкі.

Блок можа накладвацца на базу дадзеных, табліцу, шэраг ці аттрыбут. Сумесны захоп (Shared Lock) можа быць накладзены на адны дадзеныя некалькімі транзакцыямі, дазваляе ўсім транзакцыям (уключаючы якая наклала) чытанне, забараняе змену і манапольны захоп. Манапольны захоп (Exclusive Lock) можа быць накладзены толькі адной транзакцыяй, дазваляе любыя дзеянні якая наклала транзакцыі, забараняе любыя дзеянні астатнім.

Узаемаблакіроўкай лічыцца сітуацыя калі транзакцыі аказваюцца ў рэжыме чакання, які доўжыцца бясконца доўга

Прыклад. Першая транзакцыя чакае вызвалення звестак захопленых другой, у той час як другая чакае вызвалення звестак, захопленых першай.

Аптымістычнае вырашэнне праблемы ўзаемаблакіровак дазваляе ўзаемаблакіроўцы адбыцца, але затым аднаўляе сістэму адкочваючы адну з транзакцый, якія ўдзельнічаюць ва ўзаемаблакіроўцы

З вызначанай перыядычнасцю вырабляецца пошук узаемаблакіровак. Адзін са спосабаў выяўлення - па часе, гэта значыць лічыць што ўзаемаблакіроўка адбылася калі транзакцыя выконваецца занадта доўга. Калі ўзаемаблакіроўка знойдзена, то адна з транзакцый адкочваецца, што дае магчымасць іншым транзакцыям якія ўдзельнічаюць ва ўзаемаблакіроўцы завяршыцца. Выбар ахвяры можа быць заснаваны на кошце транзакцый або іх старшынстве (Wait-Die і Wound-wait схемы).

Кожнай транзакцыі T прысвойваецца часовая пазнака TS якая змяшчае час пачатку выканання транзакцыі.

Wait-Die.

Калі TS(Ti) < TS(Tj), То Ti чакае, інакш Ti адкочваецца і пачынаецца зноўку з той жа часовай пазнакай.

Калі маладая транзакцыя захапіла рэсурс, а больш старая запытвае той жа рэсурс, то старэйшай транзакцыі дазволена чакаць. Калі больш старая транзакцыя захапіла рэсурс, то маладая транзакцыя, якая запытвае гэты рэсурс, будзе адкачана.

Wound-wait.

Калі TS(Ti) < TS(Tj), То Tj адкочваецца і пачынаецца нанова з той жа часовай пазнакай, інакш Ti чакае.

Калі маладзейшая транзакцыя захапіла рэсурс, а больш старая транзакцыя запытвае гэты ж рэсурс, то маладая транзакцыя будзе адкачана. Калі больш старая транзакцыя захапіла рэсурс, то маладзейшай транзакцыі, якая запытвае гэты рэсурс дазволена чакаць. Выбар ахвяры заснаваны на старшынстве прадухіляе з'яўленне ўзаемаблакіровак, але адкочвае транзакцыі якія не знаходзяцца ў стане ўзаемаблакіроўкі. Праблема заключаецца ў тым, што транзакцыі могуць адкочвацца шмат разоў, т.я. больш старая транзакцыя можа доўга ўтрымліваць рэсурс.

Песімістычнае рашэнне праблемы ўзаемаблакіровак не дазваляе транзакцыі пачаць выкананне калі ёсць рызыка ўзнікнення ўзаемаблакіроўкі

Для выяўлення ўзаемаблакіроўкі будуецца граф (граф чакання, wait-for-graph), вяршыні якога транзакцыі, а рэбры накіраваны ад транзакцый, якія чакаюць вызвалення дадзеных да транзакцыі, якія захапілі гэтыя дадзеныя. Лічыцца, што ўзаемаблакіроўка адбылася, калі граф мае зацыкленасць. Пабудова графа чакання, асабліва ў размеркаваных БД, дарагая працэдура.

Двухфазная блакіроўка - прадухіленне ўзаемаблакіровак шляхам захопу ўсіх рэсурсаў выкарыстоўваных транзакцыяй у пачатку транзакцыі і вызвалення іх у канцы

Усе блакавальныя аперацыі павінны папярэднічаць першай разблакавальнай. Мае дзве фазы - Growing Phase пры якой адбываецца назапашванне захопаў і Shrinking Phase пры якой адбываецца вызваленне захопаў. Пры немагчымасці захопу аднаго з рэсурсаў транзакцыя пачынаецца спачатку. Магчыма сітуацыя, калі транзакцыя не зможа захапіць патрэбныя рэсурсы, напрыклад, калі некалькі транзакцый будуць канкураваць за адны рэсурсы.

Двухфазны коміт забяспечвае выкананне комміта на ўсіх рэпліках БД

Кожная БД уносіць інфармацыю аб дадзеных якія будуць зменены ў лог і адказвае каардынатару ОК (Voting Phase). Пасля таго як усё адказалі ОК каардынатар адсылае сігнал які абавязвае ўсіх вырабіць комит. Пасля коміта сервера адказваюць ОК, калі хоць адзін не адказаў ОК, то каардынатар адсылае сігнал адмены змен усім серверам (Completion Phase).

Метад часовых пазнак

Больш старая транзакцыя адкочваецца пры спробе доступу да дадзеных, задзейнічаных маладзейшай транзакцыяй

Кожнай транзакцыі прызначаецца часовая пазнака TS адпаведная часу пачатку выканання. Калі Ti старэй Tj, То TS(Ti) < TS(Tj).

Калі транзакцыя адкочваецца, ёй прызначаецца новая часавая пазнака. Кожны аб'ект дадзеных Q задзейнічаны транзакцыяй пазначаецца двума пазнакамі. W-TS(Q) - часовая пазнака самай маладой транзакцыі, якая паспяхова выканала запіс над Q. R-TS(Q) - часовая пазнака самай маладой транзакцыі, якая выканала запіс чытання над Q.

Калі транзакцыя T запытвае чытанне дадзеных Q магчымыя два варыянты.

Калі TS(T) < W-TS(Q), гэта значыць дадзеныя былі абноўленыя маладзейшай транзакцыяй, то транзакцыя T адкочваецца.

Калі TS(T) >= W-TS(Q), то чытанне выконваецца і R-TS(Q) становіцца MAX(R-TS(Q), TS(T)).

Калі транзакцыя T запытвае змену дадзеных Q магчымыя два варыянты.

Калі TS(T) < R-TS(Q), гэта значыць дадзеныя ўжо былі прачытаныя маладзейшай транзакцыяй і калі вырабіць змену, то ўзнікне канфлікт. Транзакцыя T адкочваецца.

Калі TS(T) < W-TS(Q), гэта значыць транзакцыя спрабуе перазапісаць навейшае значэнне, транзакцыя T адкочваецца. У астатніх выпадках змена выконваецца і W-TS(Q) становіцца роўным TS(T).

Не патрабуецца дарагой пабудовы графа чакання. Больш старыя транзакцыі залежаць ад навейшых, такім чынам у графе чакання няма цыклаў. Няма ўзаемаблакіровак, паколькі транзакцыі не чакаюць, а адразу адкочваюцца. Магчымы каскадныя адкаты. Калі Ti адкацілася, а Tj прачытала дадзеныя якія змяніла Ti, То Tj таксама павінна адкаціцца. Калі пры гэтым Tj ужо была закаммічана, то ўзнікне парушэнні прынцыпу ўстойлівасці.

Адно з рашэнняў каскадных адкатаў. Транзакцыя выконвае ўсе аперацыі запісы ў канцы, прычым астатнія транзакцыі абавязаны чакаць завяршэнні гэтай аперацыі. Транзакцыі чакаюць коміты перад чытаннем.

Thomas write rule — варыяцыя метаду часавых пазнак пры якой дадзеныя абноўленыя маладзейшай транзакцыяй забаронена перазапісваць больш старой

Транзакцыя T запытвае змену дадзеных Q. Калі TS(T) < W-TS(Q), гэта значыць транзакцыя спрабуе перазапісаць навейшае значэнне, транзакцыя T не адкочваецца як у метадзе часавых пазнак.

Крыніца: habr.com

Дадаць каментар