Mga transaksyon at ang kanilang mga mekanismo ng kontrol

Mga Transaksyon

Ang transaksyon ay isang pagkakasunud-sunod ng mga operasyon sa data na may simula at wakas.

Ang isang transaksyon ay ang sunud-sunod na pagpapatupad ng mga operasyon sa pagbasa at pagsulat. Ang pagtatapos ng isang transaksyon ay maaaring alinman sa pag-save ng mga pagbabago (commit) o ​​pagkansela ng mga pagbabago (rollback). Kaugnay ng isang database, ang isang transaksyon ay binubuo ng ilang mga kahilingan na itinuturing bilang isang kahilingan.

Dapat matugunan ng mga transaksyon ang mga katangian ng ACID

Atomicity. Ang transaksyon ay maaaring ganap na natapos o hindi.

Hindi pagbabago. Kapag nakumpleto ang isang transaksyon, ang mga paghihigpit na ipinataw sa data (halimbawa, mga hadlang sa database) ay hindi dapat labagin. Ang pagkakapare-pareho ay nagpapahiwatig na ang system ay ililipat mula sa isang tamang estado patungo sa isa pang tamang estado.

Isolation. Ang mga transaksyong tumatakbo nang magkatulad ay hindi dapat makaimpluwensya sa isa't isa, halimbawa, baguhin ang data na ginagamit ng isa pang transaksyon. Ang resulta ng pagsasagawa ng mga parallel na transaksyon ay dapat na kapareho ng kung ang mga transaksyon ay isinagawa nang sunud-sunod.

Pagpapanatili. Sa sandaling nakatuon, ang mga pagbabago ay hindi dapat mawala.

Log ng transaksyon

Ang log ay nag-iimbak ng mga pagbabagong ginawa ng mga transaksyon, tinitiyak ang atomicity at katatagan ng data sa kaganapan ng pagkabigo ng system

Ang log ay naglalaman ng mga halaga na mayroon ang data bago at pagkatapos itong mabago ng transaksyon. Ang diskarte sa write-ahead na log ay nangangailangan ng pagdaragdag ng log entry tungkol sa mga nakaraang halaga bago magsimula, at tungkol sa mga huling halaga pagkatapos makumpleto ang transaksyon. Sa kaganapan ng isang biglaang paghinto ng system, binabasa ng database ang log sa reverse order at kinakansela ang mga pagbabagong ginawa ng mga transaksyon. Ang pagkakaroon ng nakatagpo ng isang naantala na transaksyon, ang database ay nagpapatupad nito at gumagawa ng mga pagbabago tungkol dito sa log. Ang pagiging nasa estado sa oras ng pagkabigo, binabasa ng database ang log in forward order at ibinabalik ang mga pagbabagong ginawa ng mga transaksyon. Sa ganitong paraan, napapanatili ang katatagan ng mga transaksyong nagawa na at ang atomicity ng naantala na transaksyon.

Ang simpleng muling pagpapatupad ng mga nabigong transaksyon ay hindi sapat para sa pagbawi.

Halimbawa. Ang user ay mayroong $500 sa kanyang account at nagpasya ang user na bawiin ito mula sa isang ATM. Dalawang transaksyon ang isinasagawa. Binabasa ng una ang halaga ng balanse at kung may sapat na pondo sa balanse, naglalabas ito ng pera sa gumagamit. Ibinabawas ng pangalawa ang kinakailangang halaga mula sa balanse. Sabihin nating nag-crash ang system at nabigo ang unang operasyon, ngunit nangyari ang pangalawa. Sa kasong ito, hindi kami makakapagbigay muli ng pera sa user nang hindi ibinabalik ang system sa orihinal nitong estado na may positibong balanse.

Mga antas ng pagkakabukod

Read Committed

Ang problema sa Dirty Read ay maaaring basahin ng isang transaksyon ang intermediate na resulta ng isa pang transaksyon.

Halimbawa. Ang paunang halaga ng balanse ay $0. Nagdaragdag ang T1 ng $50 sa iyong balanse. Binabasa ng T2 ang halaga ng balanse ($50). Itinatapon ng T1 ang mga pagbabago at paglabas. Ang T2 ay nagpapatuloy sa pagpapatupad na may maling data ng balanse.

Ang solusyon ay basahin ang nakapirming data (Read Committed), na nagbabawal sa pagbabasa ng data na binago ng transaksyon. Kung binago ng transaksyon A ang isang tiyak na hanay ng data, ang transaksyon B, kapag ina-access ang data na ito, ay mapipilitang maghintay para makumpleto ang transaksyon A.

Paulit-ulit na Pagbasa

Problema sa Lost Updates. Ang T1 ay nagse-save ng mga pagbabago sa ibabaw ng mga pagbabago ng T2.

Halimbawa. Ang paunang halaga ng balanse ay $0 at dalawang transaksyon ang sabay-sabay na palitan ang balanse. Binasa ng T1 at T2 ang balanse na $0. T2 pagkatapos ay nagdaragdag ng $200 hanggang $0 at i-save ang resulta. Ang T1 ay nagdaragdag ng $100 hanggang $0 at nai-save ang resulta. Ang huling resulta ay $100 sa halip na $300.

Hindi nauulit na problema sa pagbabasa. Ang paulit-ulit na pagbabasa ng parehong data ay nagbabalik ng iba't ibang mga halaga.

Halimbawa. Nagbabasa ang T1 ng halaga ng balanse na $0. Ang T2 ay nagdaragdag ng $50 sa balanse at nagtatapos. Binabasa muli ng T1 ang data at nakahanap ng pagkakaiba sa nakaraang resulta.

Tinitiyak ng Repeable Read na ang pangalawang pagbabasa ay magbabalik ng parehong resulta. Ang data na nabasa ng isang transaksyon ay hindi mababago sa iba hanggang sa makumpleto ang transaksyon. Kung nabasa ng transaksyon A ang isang tiyak na hanay ng data, ang transaksyon B, kapag ina-access ang data na ito, ay mapipilitang maghintay para makumpleto ang transaksyon A.

Nakaayos na pagbabasa (Serializable)

Problema sa Phantom Reads. Dalawang query na pumipili ng data batay sa isang partikular na kundisyon ay nagbabalik ng magkaibang mga halaga.

Halimbawa. Hinihiling ng T1 ang bilang ng lahat ng user na ang balanse ay higit sa $0 ngunit mas mababa sa $100. Ibinabawas ng T2 ang $1 mula sa isang user na may balanseng $101. Muling iniisyu ng T1 ang kahilingan.

Nakaayos na pagbabasa (Serializable). Ang mga transaksyon ay isinasagawa bilang ganap na sunud-sunod. Ipinagbabawal na i-update o magdagdag ng mga tala na nasa loob ng mga tuntunin ng kahilingan. Kung ang transaksyon A ay humiling ng data mula sa buong talahanayan, ang buong talahanayan ay naka-freeze para sa iba pang mga transaksyon hanggang sa makumpleto ang transaksyon A.

Tagapag-iskedyul

Itinatakda ang pagkakasunud-sunod kung saan dapat isagawa ang mga operasyon sa panahon ng mga parallel na transaksyon

Nagbibigay ng tinukoy na antas ng paghihiwalay. Kung ang resulta ng mga operasyon ay hindi nakasalalay sa kanilang pagkakasunud-sunod, kung gayon ang mga naturang operasyon ay commutative (Permutable). Ang pagbabasa ng mga operasyon at pagpapatakbo sa iba't ibang data ay commutative. Ang mga operasyong read-write at write-write ay hindi commutative. Ang gawain ng scheduler ay ang pag-interleave sa mga operasyong isinagawa ng mga parallel na transaksyon upang ang resulta ng pagpapatupad ay katumbas ng sequential execution ng mga transaksyon.

Mga mekanismo para sa pagkontrol ng mga parallel na trabaho (Concurrency Control)

Ang optimistiko ay batay sa pag-detect at paglutas ng mga salungatan, ang pessimistic ay batay sa pagpigil sa mga salungatan na lumitaw.

Sa optimistikong diskarte, maraming user ang may mga kopya ng data na magagamit nila. Ang unang taong makakumpleto sa pag-edit ay nagse-save ng mga pagbabago, habang ang iba ay dapat pagsamahin ang mga pagbabago. Ang isang optimistikong algorithm ay nagbibigay-daan sa salungatan na mangyari, ngunit ang sistema ay dapat makabawi mula sa salungatan.

Sa isang pessimistic na diskarte, pinipigilan ng unang user na kumuha ng data ang iba sa pagtanggap ng data. Kung bihira ang mga salungatan, matalinong pumili ng optimistikong diskarte, dahil nagbibigay ito ng mas mataas na antas ng pagkakatugma.

Nagla-lock

Kung ang isang transaksyon ay may naka-lock na data, ang ibang mga transaksyon ay dapat maghintay hanggang sa ito ay ma-unlock kapag ina-access ang data.

Maaaring ma-overlay ang isang block sa isang database, table, row, o attribute. Maaaring ipataw ang Shared Lock sa parehong data ng ilang transaksyon, pinapayagan ang lahat ng transaksyon (kabilang ang nagpataw nito) na basahin, ipinagbabawal ang pagbabago at eksklusibong pagkuha. Ang Exclusive Lock ay maaaring ipataw ng isang transaksyon lamang, pinapayagan ang anumang mga aksyon ng kahanga-hangang transaksyon, ipinagbabawal ang anumang mga aksyon ng iba.

Ang deadlock ay isang sitwasyon kung saan ang mga transaksyon ay napupunta sa isang nakabinbing estado na tumatagal nang walang katapusan.

Halimbawa. Ang unang transaksyon ay naghihintay para sa data na nakuha ng pangalawa na ilabas, habang ang pangalawa ay naghihintay para sa data na nakuha ng una na ilabas.

Ang isang optimistikong solusyon sa problema sa deadlock ay nagbibigay-daan sa deadlock na mangyari, ngunit pagkatapos ay binabawi ang system sa pamamagitan ng pag-roll back ng isa sa mga transaksyon na kasangkot sa deadlock.

Hinahanap ang mga deadlock sa ilang partikular na agwat. Ang isa sa mga paraan ng pagtuklas ay ayon sa oras, iyon ay, isaalang-alang na ang isang deadlock ay naganap kung ang transaksyon ay tumatagal ng masyadong mahaba upang makumpleto. Kapag natagpuan ang isang deadlock, isa sa mga transaksyon ay i-roll back, na nagpapahintulot sa iba pang mga transaksyon na kasangkot sa deadlock upang makumpleto. Ang pagpili ng biktima ay maaaring batay sa halaga ng mga transaksyon o kanilang seniority (Wait-Die at Wound-wait scheme).

Bawat transaksyon T isang timestamp ang itinalaga TS naglalaman ng oras ng pagsisimula ng transaksyon.

Maghintay-Mamatay.

Kung TS(Ti) < TS(Tj), Pagkatapos Ti naghihintay, kung hindi Ti gumulong pabalik at magsisimula muli sa parehong timestamp.

Kung ang isang batang transaksyon ay nakakuha ng isang mapagkukunan at ang isang mas lumang transaksyon ay humiling ng parehong mapagkukunan, kung gayon ang mas lumang transaksyon ay pinapayagang maghintay. Kung ang isang mas lumang transaksyon ay nakakuha ng resource, ang nakababatang transaksyon na humihiling sa resource na iyon ay ibabalik.

Sugat-maghintay.

Kung TS(Ti) < TS(Tj), Pagkatapos Tj gumulong pabalik at magsisimula muli sa parehong timestamp, kung hindi man Ti naghihintay

Kung ang isang mas batang transaksyon ay nakakuha ng isang mapagkukunan at ang isang mas lumang transaksyon ay humiling ng parehong mapagkukunan, pagkatapos ay ang mas batang transaksyon ay ibabalik. Kung ang isang mas lumang transaksyon ay nakakuha ng mapagkukunan, ang nakababatang transaksyon na humihiling ng mapagkukunan na iyon ay pinapayagang maghintay. Pinipigilan ng pagpili ng biktima na nakabatay sa precedence ang mga deadlock, ngunit ibinabalik ang mga transaksyong hindi deadlock. Ang problema ay ang mga transaksyon ay maaaring i-rollback ng maraming beses dahil... ang isang mas lumang transaksyon ay maaaring magkaroon ng mapagkukunan ng mahabang panahon.

Ang isang pessimistic na solusyon sa problema sa deadlock ay hindi nagpapahintulot sa isang transaksyon na magsimulang magsagawa kung may panganib ng isang deadlock.

Upang matukoy ang isang deadlock, isang graph ang binuo (waiting graph, wait-for-graph), ang mga vertice nito ay mga transaksyon, at ang mga gilid ay nakadirekta mula sa mga transaksyon na naghihintay para sa paglabas ng data sa transaksyon na nakakuha ng data na ito. Ang isang deadlock ay itinuturing na naganap kung ang graph ay may loop. Ang pagbuo ng wait graph, lalo na sa mga distributed database, ay isang mamahaling pamamaraan.

Two-phase locking - pinipigilan ang mga deadlock sa pamamagitan ng pag-agaw ng lahat ng mga mapagkukunan na ginagamit ng isang transaksyon sa simula ng transaksyon at ilalabas ang mga ito sa dulo

Ang lahat ng mga operasyon sa pagharang ay dapat na mauna sa unang pag-unlock. Mayroon itong dalawang yugto - Growing Phase, kung saan nag-iipon ang mga grip, at Shrinking Phase, kung saan inilalabas ang mga grip. Kung imposibleng makuha ang isa sa mga mapagkukunan, magsisimula muli ang transaksyon. Posible na ang isang transaksyon ay hindi makakakuha ng mga kinakailangang mapagkukunan, halimbawa, kung maraming mga transaksyon ang nakikipagkumpitensya para sa parehong mga mapagkukunan.

Tinitiyak ng two-phase commit na ang commit ay naisakatuparan sa lahat ng mga replika ng database

Ang bawat database ay naglalagay ng impormasyon tungkol sa data na babaguhin sa log at tumutugon sa coordinator na OK (Voting Phase). Matapos ang lahat ay tumugon ng OK, ang coordinator ay nagpapadala ng isang senyas na nag-oobliga sa lahat na mangako. Pagkatapos mag-commit, ang mga server ay tumugon ng OK; kung hindi bababa sa isa ang hindi tumugon ng OK, pagkatapos ay ang coordinator ay magpapadala ng isang senyas upang kanselahin ang mga pagbabago sa lahat ng mga server (Completion Phase).

Paraan ng timestamp

Ang isang mas lumang transaksyon ay ibinabalik kapag sinusubukang i-access ang data na kasangkot sa isang mas batang transaksyon

Ang bawat transaksyon ay binibigyan ng timestamp TS naaayon sa oras ng pagsisimula ng pagpapatupad. Kung Ti mas matanda Tj, Pagkatapos TS(Ti) < TS(Tj).

Kapag na-roll back ang isang transaksyon, itatalaga ito ng bagong timestamp. Ang bawat object ng data Q kasangkot sa transaksyon ay minarkahan ng dalawang label. W-TS(Q) β€” timestamp ng pinakabatang transaksyon na matagumpay na nakumpleto ang isang talaan Q. R-TS(Q) β€” timestamp ng pinakabatang transaksyon na nagsagawa ng read record sa Q.

Kapag ang transaksyon T mga kahilingan na basahin ang data Q Mayroong dalawang mga pagpipilian.

Kung TS(T) < W-TS(Q), iyon ay, ang data ay na-update ng isang mas bata na transaksyon, pagkatapos ay ang transaksyon T gumulong pabalik.

Kung TS(T) >= W-TS(Q), pagkatapos ay isinagawa ang pagbabasa at R-TS(Q) ay nagiging MAX(R-TS(Q), TS(T)).

Kapag ang transaksyon T humihiling ng mga pagbabago sa data Q Mayroong dalawang mga pagpipilian.

Kung TS(T) < R-TS(Q), ibig sabihin, ang data ay nabasa na ng isang mas batang transaksyon at kung may gagawing pagbabago, magkakaroon ng salungatan. Transaksyon T gumulong pabalik.

Kung TS(T) < W-TS(Q), iyon ay, sinusubukan ng transaksyon na i-overwrite ang isang mas bagong halaga, ang transaksyon T ay ibinabalik. Sa ibang mga kaso, ang pagbabago ay isinasagawa at W-TS(Q) nagiging pantay TS(T).

Hindi kailangan ng mamahaling waiting graph construction. Ang mga mas lumang transaksyon ay nakadepende sa mga mas bago, kaya walang mga cycle sa wait graph. Walang deadlocks dahil hindi hinintay ang mga transaksyon bagkus ay binabalik agad. Posible ang mga cascading rollback. Kung Ti gumulong palayo at Tj Binasa ko ang data na binago ko Ti, Pagkatapos Tj dapat ding gumulong pabalik. Kung kasabay Tj nagawa na, pagkatapos ay magkakaroon ng paglabag sa prinsipyo ng katatagan.

Isa sa mga solusyon sa mga cascading rollback. Kinukumpleto ng isang transaksyon ang lahat ng pagpapatakbo ng pagsulat sa dulo, at dapat maghintay ang ibang mga transaksyon para makumpleto ang operasyong iyon. Ang mga transaksyon ay naghihintay na gawin bago basahin.

Thomas write rule - isang variation ng timestamp method kung saan ang data na na-update ng isang mas bata na transaksyon ay ipinagbabawal na ma-overwrite ng isang mas luma.

Transaksyon T humihiling ng mga pagbabago sa data Q. Kung TS(T) < W-TS(Q), ibig sabihin, sinusubukan ng transaksyon na i-overwrite ang isang mas bagong halaga, ang transaksyon T ay hindi ibinabalik tulad ng sa timestamp na paraan.

Pinagmulan: www.habr.com

Magdagdag ng komento