Tema: Re: Need nuomonės iš šono - DB
Autorius: Laimis
Data: 2011-12-09 02:41:50
2x50 rašė:

> Nevisai. Problema yra iš esmės FIFO uždavinyje, o jam realizuoti
> SERIALIZABLE tinka.
>
> Nemanau, kad serializable is viso ka nors keicia siuo atveju, bent jau
> ne gretaveikos prasme. Problema yra tame, kad visos aktyvios

Keičia logikos ir uždavinio prasme. FIFO. Nereikia dirty reads (eilė 
papildyta)? Tikrai nereikia, tad mažiausiai READ COMMITTED. Nereikia 
non-repeatable reads? Veikiausiai nepageidautina (konkrečios programos 
detalės neaiškios), tad REPEATABLE READS. Nereikia phantomų? Veikiausiai 
nepageidautina (konkrečios programos detalės neaiškios), tad 
SERIALIZABLE. Tai — bendru atveju.

O MySQL'o atveju, greitaveikos prasme nebus jokio skirtumo (Domas gal 
pataisys) ar tai REPEATABLE READS (default isolation lygis MySQL'e), ar 
SERIALIZABLE, nes MySQL'o SERIALIZABLE yra REPEATABLE READS variacija
su neesminiais skirtumais. Juo labiau, kad veikimo logika yra FIFO (ir 
įrašai apdorojami nuosekliai). Tačiau nežinant kas ten konkrečiai 
daroma, turint FIFO uždavinį, manau geriau rekomenduoti SERIALIZABLE.
   transakcijos bando uzrakinti viena ir ta pati irasa, todel ju laukimas
> yra visiskai beprasmiskas.

FIFO. Jų laukimas yra visiškai neišvengiamas.
Net ir įvedus konkurentiškumą čia jau siūlytais būdais, transakcijos 
sustoja į nuoseklią eilutę besidalindamos id, o išsilygiagretina tik po 
to. Ir beje, konkrečiu atveju, rakinamas ne vieną įrašas, o jų eilė (gap 
lock), tad net ir FIFO eilės papildymo transakcija (su mažėjančiu id, 
pagal viską) lygiagrečiai negalima ir stoja į tą pačią eilutę...


> nores daryti lygiai ta pati (X lockas tam paciam irasui), tai jos visos
> tusciai lauks kol baigsis pirmoji, nes, kaip zinia, X ir X kombinacija

Kodėl tuščiai? Neišvengiamai. FIFO :-)

> Supaprastintai stai kas ivyks siuo konkreciu atveju, mano isivaizdavimu:
>
> --> start transaction t1
> --> start transactio t2
> --> t1 SELECT * FROM `table` ORDER BY ID ASC LIMIT 1 (tarkim grazina id=5)
> --> t2 SELECT * FROM `table` ORDER BY ID ASC LIMIT 1 (grazins ta pati
> irasa id=5)
> --> t1 DELETE FROM `table` WHERE `ID` = 5
> --> t1 sukuria X locka irasui id=5
> --> t2 DELETE FROM `table` WHERE `ID` = 5
> --> t2 negali sukurti X locko irasui id=5, todel statoma i eile
> --> t1 commit
> --> t2 dabar gali sukurti X locka irasui id=5
>
> Tik beda tame, kad iraso jau nebera, todel sita transakcija viska dare
> tusciai. Klausimas tik kaip MySQL susidoroja su tokia situacija, grazina
> exceptiona ar ne.

FIFO logika reikalauja ir, jei nepastebėjai, rakinamas jau SELECT'as 
(FOR UPDATE). Tad transakcijos sustoja į eilę jau skaitydamos.
Kita vertus, MySQL'e viskas vyktų taip (kai autocommit=0, isolation 
level SERIALIZABLE):

t1 SELECT'as užrakina (gap lock) įrašą. t2 SELECT'as užrakina (gap lock) 
įrašą.
t1 transakcija ties DELETE'u lauks, kol t2 transakcija commit'ins. t2 
DELETE'as, savo ruožtu, stoja į eilę, paskui t1 irrr...iššaukia 
deadlock'ą: ERROR 1213 (40001): Deadlock found when trying to get lock; 
try restarting transaction. t2 atšaukiama, o t1 tęsia davo darbą ir 
įvykdomas DELETE.


> Net jei MySQL ir pasinaudos multi-verioningu ir t2 suras ta irasa,
> visvien ji negales ivykdyti delete komandos ir prasisuks tusciai, nes
> iraso jau nera.

Kaip jau rašiau, taip neįvyks. Įvyks deadlock'as ir visa tai savaime 
išsisprendžia (tiesa, negaliu pasakyti, kada ir kaip deadlock'ai jau 
atsilieptų spartai, bet bendru atveju tai nėra problema)

Tavo minėtos situacijos (ir darbas tuščiai) įvyktų tik tuomet, jei 
isolation lygis būtų net žemesnis, nei numatytasis (REPEATABLE READ), 
t.y. READ COMMITED.