Samanaikaisuuden hallintaohjelmoinnin näkökulmasta
TiedonhallintaaTiedonhallintaaJaakko Rantanen
1. versio 14.9.1998
Päivitetty 11.3.2009 (huojo)
21.04.23
2
SamanaikaisuusYhden vai monen asiakkaan palvelu
Tapahtumat voivat olla sarjallisia (serial), ts.kukin tapahtuma joutuu odottamaan edellisen päättymistä.
Sarjallisessa suorittamisessa samanaikaisuusaste on yksi (1), ts. pystytään suorittamaan vain yhtä tapahtumaa kerrallaan. Alkeellinen ohjelmointimenettely olisi kokonaisen tiedoston tai tietokannan taulun lukinta sovelluksesta esimerkiksi lock-komennolla, mikä ei kelpaa tietokantapalvelimen käytössä!
21.04.23
3
Sarjallistuvuus
• Sarjallinen (serial) ajoitustoimii kuin "köyhän talon porsaat", mutta siinä on vain yksi samanaikainen asiakas.
• Tapahtumajoukon TX1, TX2,... ajoitus on sarjallistuva (serializable), jos se tuottaa saman eheän lopputuloksen kuin jokin sarjallinen ajoitus (kaikista eri järjestysvaihtoehdoista).
Voi olla monta samanaikaista asiakasta.Tällä on vankka teoreettinen tausta, jota ei nyt tarkastella lähemmin.
TX1, TX2, TX3
21.04.23
4
Transaktio sovelluksessa• Transaktion alku on joko
– eksplisiittinen: komento begin transaction
– implisiittinen: ei komentoa, vaan • ohjelman(osan) käynnistys tai• edellisen transaktion päättyminen
• Transaktio päättyy joko– vahvistukseen: komento commit – peruutukseen: komentoon rollback
tai DBMSn suorittamaan automaattiseen peruutukseen, jos ei vahvistusta tule
sovellus
DBMS
TX
21.04.23
5
Atomisuus
• Transaktio suoritetaan aina jakamattomana eli atomisena (atomic)
Kaikki tai ei mitään!
21.04.23
6
Transaktioita käytettäväVARO!• Mm. ODBC ja JDBC, Accessin Jet
Engine,... käyttävät autocommit -tilamuuttujaa, jonka arvot ovat on tai off. Oletusarvo on on.
• Autocommit ei sovi normaaliin sovellukseen
• Yleensä on annettava aluksi komento set autocommit off
21.04.23
7
Miten kävisi tilisiirrossa?
set autocommit on !!!
lue tilin tA saldo sA
kirjoita sA = sA-100
lue tilin tB saldo sB
linjahäiriö/system crash/...
kirjoita sB = sB+100
set autocommit on !!!
lue tilin tA saldo sA
kirjoita sA = sA-100
lue tilin tB saldo sB
linjahäiriö/system crash/...
kirjoita sB = sB+100
21.04.23
8
Transaktiot ja luokkien palvelut
• Operaatioiden eli palvelupyyntöjen suunnittelussa on transaktioeheys säilytettävä
• Useimmiten luonnollisina tehtävinä
TILI
numerosaldo
hae()muuta()
TILI
numerosaldo
siirto(tilille, rahaMäärä)
21.04.23
9
Samanaikaisuuden hallinnan toteutustekniikoita
• DBMSien tarjoamat toteutustavat: – lukitus– versiointi
• Itse ohjelmoitu toteutustapa:– aikaleimojen hallinta
• tarpeelliseksi katsotut tiedon osat (esim. rivi) varustetaan aikaleima-sarakkeella (on myös ylläpidettävä)
• jokaisen luku- ja päivityskäskyn yhteydessä päätellään aikaleimoista onko joku muu ollut käsittelemässä ko. tietoja samaan aikaan
Tässä yhteydessä ei käsitellä aikaleimoilla ohjelmointia lähemmin.
21.04.23
10
Transaktion hallinta• Tapahtumien samanaikaisuutta
(concurrency) hallitsee tietokantapalvelin sekä mahdollinen tapahtumanhallinta-ohjelmisto (CICS, MTS, Tuxedo, M3,...)
• Sovellus pyytää tietokantapalvelimelta tai tapahtumanhallintajärjestelmältä tehtäväänsä sopivaa eristyvyystasoa (Isolation Level).
• Eristyvyystaso ilmaisee transaktion eristyvyyttä eli riippumattomuutta muista samanaikaisista transaktioista (tapahtumista).
21.04.23
11
Samanaikaisuuden ongelmat, by Chris Date
Tyypilliset ongelmatilanteet (anomalies):1 Hukatun päivityksen ongelma (lost update)
– päällekirjoitus2 Keskeneräisen käsittelyn ongelma
(uncommitted dependency)
a) luetaan peruutettavab) päivitetään peruutettava
3 Ristiriitaisen tulkinnan ongelma (inconsistent analysis)
a) eritahtinen päivitysb) uusien rivien ongelma (phantom rows)
21.04.23
12
1)Hukatun päivityksen ongelma
Tili X, saldo 1000Transaktio A
”nostan 200 €”Transaktio B
”nostan 500 €”
lue tili Xlue tili X
Saldo = saldo - 200
Saldo = saldo - 500
Kirjoita tili xKirjoita tili x
aika
Aina estettävä
21.04.23
13
2 a) Keskeneräisen luku (dirty read)
Tili X, saldo 1000Transaktio A
”katson saldon”Transaktio B
”nostan 500 €”
lue tili X
Saldo = saldo - 500
ROLLBACK
aika
lue tili X
"Dirty read"
kirjoita tili X
21.04.23
14
2 b) Keskeneräisen päivitys
Tili X, saldo 1000Transaktio A
”nostan 200 €”Transaktio B
”nostan 500 €”
lue tili X
Saldo = saldo - 500
ROLLBACK
aika
lue tili X
Saldo = saldo - 200
Kirjoita tili x
Aina estettävä
21.04.23
15
3 a) Eritahtinen päivitys (nonrepeatable read)
Tili 1, saldo 1000Tili 2, saldo 2000Tili 3, saldo 5000Transaktio A
”Tilien 1,2 ja 3saldojen summa”
Transaktio B”siirrän 500 €
tililtä 3 tilille 1”
lue tili 3Saldo = saldo - 500
aika
lue tili 1summa = saldo
lue tili 2summa = summa+saldo
lue tili 3summa = summa+saldo
kirjoita tili 1Saldo = saldo + 500COMMIT
"Nonrepeatable read"
21.04.23
16
3 b) Uusien rivien ongelma (phantom)
Tili 1, saldo 1000 ...Tili 4, saldo 2000Tili 5, saldo 5000
Transaktio A”Tilien 1-N
saldojen summa”
Transaktio BX:”avaan tilin 2 ja talletan 1000€”
perusta tili 2saldo = 1000
aika
lue tili 1summa = saldo
lue tili 4summa = summa+saldo
lue tili 5summa = summa+saldo
kirjoita tili 2COMMIT
"Phantom"
21.04.23
17
SQL-92 Isolation levels
SERIALIZABLE
READ COMMITTED
READ UNCOMMITTED
REPEATABLE READ
Dirty Read PhantomsNonrepeatable Read
mahdollinen mahdollinen mahdollinen
Ei mahdollinen mahdollinen mahdollinen
Ei mahdollinen Ei mahdollinen mahdollinen
Ei mahdollinen Ei mahdollinenEi mahdollinen
• Eristyvyystasojen määritelmät
21.04.23
18
Käyttö ohjelmassa
• Transaktiokohtaisesti voi antaa komennon
set transaction isolation level
ohjelmassa tehtävän vaatimuksen mukaan
read uncommittedread committedrepeatable readserializable
21.04.23
19
Tekniikkana lukitus• DBMS voi hallita samanaikaisuutta esim.
lukitsemalla tietoja (nk. pessimistinen menetelmä).
• Lukon piirteitä: aste (yksityinen/jaettu/...), rakeisuus (predikaatti/rivi/sivu/taulu), ym.
– lukulukko on jaettu (S shared), muut saavat lukea,– kirjoituslukko yksityinen (X exclusive), poissulkeva.
• Käytännössä vanhin ja yleisin tekniikka• Tuotteiden toteutuksissa merkittäviä eroja
mm. tehokkuudessa ja muistin käytössä
21.04.23
20
Lukkiuma• Lukkiuma eli lukkiutuma (deadlock) voi
syntyä, jos nk. odotusverkossa on sykli:
• Syklissä voi olla useitakin transaktioita• Purku: DBMS valitsee uhri-transaktion
ja pysäyttää sen
TX1 TX2 nk. "wait-for-graph"
TX1 on lukinnut tiedon X ja haluaisi tiedon YTX2 on lukinnut tiedon Y ja haluaisi tiedon X
21.04.23
21
Lukkiumaan varautuminen• Entä jos oma ohjelma joutuu uhriksi?• DBMS antaa uhrille SQLSTATE-koodin
– Transaktion ohjelmoinnissa pitää tutkia SQLSTATE ja varautua käynnistykseen• on tiedettävä pitääkö käynnistyä itse uudelleen• vai käynnistääkö ajoympäristö (esim. jokin TX
Manager)
• Tuotteiden toteutuksissa pahoja erojaLähes kaikki DBMSt tekevät uhri-transaktiolle rollbackin, mutta esim. Oracle7 peruu vain uhrin viimeisen käskyn!(Miten ohjelmoijan on osattava tähän Oraclen tilanteeseen varautua?)
21.04.23
22
Kaksivaiheinen lukitseminen• Kaksivaiheinen lukituskäytäntö (2PL = two
phase locking) tarkoittaa lukkiumia torjuvaa ohjelman suoritustapaa
• Transaktio TX noudattaa 2PL-käytäntöä, jos kaikki lukitusoperaatiot TXssa edeltävät ensimmäistä lukon vapautusta
• Käytännössä vähintään repeatable read kaikki lukot pidetään commitiin asti.
Tämä on nk. ankara (strict) 2PL.
21.04.23
23
Tekniikkana versiointi• Jokainen transaktio käsittelee omaa
versiotaan (eli omaa kopiota) datasta.• Vasta commit-hetkellä DBMS ilmoittaa
mahdollisen konfliktin: että joku muu on ehtinyt muuttaa "originaali"dataa
• Nopein voittakoon, muut aloittakoot alusta!
• Kyky uudelleenaloitukseen konfliktin jälkeen on toteutettava ohjelman rakenteeseen.
• Versiointi on optimistinen menetelmä "eihän nyt
tule konfliktia", lukinta pessimistinen "kumminkin nyt tulee konflikti"