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.