Dziwne zachowanie transakcji

0

Mam tabelę dane, która ma dwa atrybuty - x i y, ponad milion wierszy, początkowo wszystkie równe zeru. Następnie dwóch użytkowników równocześnie będzie wykonywało następujące transakcje:

T1 wykonuje user1

START TRANSACTION;
	UPDATE dane SET x=2;
COMMIT;

T2 wykonuje user2

START TRANSACTION;
	UPDATE dane SET y=100 WHERE x=2;
COMMIT;

Przy czym T1 zacznie się wykonywać ok. sekundę przed T2. Oczekiwałbym, że na atrybucie y pozostaną zera - T2 nie widzi aktualizacji wprowadzonych przez T1 (a taki update trwa ok. 30 sekund), tzn. na atrybucie x widzi same zera zatem update z T2 zawsze zawiedzie.

Ale tak się jednak nie dzieje, co bardzo mnie dziwi - może mi ktoś wyjaśnić dlaczego?

0

Poczytaj o poziomach izolacji.

0

Bo istnieje coś takiego jak poziom izolacji transakcji. W najbardziej trywialnym przypadku izolacja jest zapewniana za pomocą two-phase-lock -> transakcja T1 dostaje locka na pisanie (czyli locka exclusive) bo chce pisać do bazy. Jeśli jest założony taki lock to nikt inny nie może dostać locka ani do pisania ani do czytania. W efekcie T2 musi poczekać aż T1 skończy pisać żeby mogła zacząć czytać.

0

Moglibyście mi napisać jak to się robi? Bo w dokumentacji jak i w sieci materiały są fatalne...

0

Polecam:
http://www.amazon.com/Database-Systems-Complete-Book-2nd/dp/0131873253
Rozdział 18 jest właśnie na ten temat

0

Bardzo pilnie potrzebuję to na teraz... Czy naprawdę nie mogę poprosić o kilka linijek wytłumaczenia jak to się implementuje i w skrócie który rodzaj kiedy się wykorzystuje?

0

Dwa rozdziały (18 i 19) na temat implementacji izolacji transakcji z książki którą podałem mają 100 stron. Jak miałbym to niby napisać w kilku linijkach? o_O

0

Tak w skrócie, to trzeba Google użyć i trafić na coś takiego: http://www.slideshare.net/Michaomnicki/acid-transakcje albo takiego: http://blog.stelmisoft.pl/2010/poziom-izolacji-transakcji-w-jdbc/

0

Jaki zatem poziom transakcji powinienem ustawić, aby T2 z mojego pierwszego posta nie czekała, aż wykona się T1 ?

0

Read uncommitted, ale efekt wcale nie będzie taki jakiego byś oczekiwał, bo dostaniesz w ten sposób w losowych wierszach y=100 (tam gdzie akurat zdążyła się wykonać operacja z 1 transakcji)

0

Wykonuję polecenie
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
po czym startuję z moimi transakcjami, ale niestety nadal nie uzyskuję oczekiwanego rezultatu. Co robię źle?

0

Umiesz czytać? Napisałem ci już że NIE DA SIĘ uzyskać takiego efektu o jakim piszesz i już.

0

Przy czym T1 zacznie się wykonywać ok. sekundę przed T2. Oczekiwałbym, że na atrybucie y pozostaną zera - T2 nie widzi aktualizacji wprowadzonych przez T1 (a taki update trwa ok. 30 sekund), tzn. na atrybucie x widzi same zera zatem update z T2 zawsze zawiedzie.

Czyli chcesz, żeby transakcje były odizolowane i przy okazji, żeby jedna nie blokowała drugiej? Taki efekt możesz uzyskać przy snapshot isolation. Sprawdź czy twoja baza to obsuguje.

0

@0x200x20 MySQL nie wspiera chyba multiwersyjnej implementacji izolacji ;)

0

Ale przecież dopóki T1 nie zatwierdzi commitem wykonanych zmian to T2 nie widzi nowowstawianych krotek, tak?

0

@tomekz1991 to zależy od poziomu izolacji transakcji. Czy ty w ogole przeczytałeś co na ten temat? "Read uncommited" oznacza właśnie że T2 będzie widzieć zmodyfikowane krotki nawet jeśli T1 w ogóle ich nie skomituje tylko zrobi rollback na koniec. To się nazywa "dirty read". Multiwersyjna izolacja oznacza tyle że póki T1 nie skomituje T2 będzie widzieć "ostatnią spójną wersję bazy" czyli de facto będzie widzieć bazę bez zmian T1 aż do czasu commitu.

0

Czyli jaki rodzaj powinienem ustawić, aby T2 widziała bazę zanim T1 zrobi commita tzn. aby T2 widziała tabelę z samymi zerami? Read Commited ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1