2010-07-28 11 views
10

Co to jest blokowanie w MySQL (lub dowolnym RDBMS) i kiedy go użyjesz? Wyjaśnienie Laymana na przykładzie byłoby wspaniałe!Co to jest blokowanie w MySQL i kiedy z niego korzystać?

+0

Jest to przydatna optymalizacja dla równoczesnych użytkowników: http://www.devshed.com/c/a/MySQL/MySQL-Optimization-part-2/ –

+0

Myślę, że powinieneś zaakceptować odpowiedź @Chris. – ripper234

Odpowiedz

9

Mamy wspólne konto bankowe z saldem 200 $

idę do bankomatu i umieścić swoją kartę do urządzenia, urządzenie sprawdza, że ​​mam bilans 200 $

Tymczasem pójdziesz do banku i poprosić o 50 $, kasjer podnosi twoje konto i potwierdza, że ​​masz pieniądze.

zażądać wycofania $ 200 maszyna liczy moje pieniądze daje mi $ 200 i wyznacza równowagę w $ 0

Kasjer liczy swoje pieniądze i daje 50 $, system następnie aktualizuje saldo na rachunku jako 150 $ (200 $ - 50 $ wypłaty).

Mamy teraz 250 USD w gotówce i 150 USD na koncie. 200 USD zysku.

Baza danych powinna była używać zamków, aby zapobiec występowaniu obu transakcji w tym samym czasie.

Problem polega na tym, że każda transakcja zostanie wykonana w taki sposób, że stracimy współbieżność i wydajność będzie ucierpiała, więc są różne transaction isolation levels, które są używane w zależności od scenariusza, na przykład możesz nie dbać o to, że ktoś może modyfikować dane, które został odczytany w transakcji.

http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

Należy nauczyć i zrozumieć te scenariusze, gdzie mają one zastosowanie.

+0

Dzięki @Chris Diver wspaniałe wyjaśnienie! Rozumiem to teraz ;-) – Imran

3

Kilka dni temu odpowiedziałem a question on SO i dał przykład demonstrujący sytuację, w której locking umożliwia wielu użytkownikom jednocześnie wstawić wiersze w tabeli z zwiększany id, bez użycia AUTO_INCREMENT.

Rozważmy następujący schemat jako przykład:

CREATE TABLE demo_table (id int) ENGINE=INNODB; 

-- // Add few rows 
INSERT INTO demo_table VALUES (1), (2), (3); 

Wtedy możemy wykonać następujące czynności:

START TRANSACTION; 

-- // Get the MAX(id) so that we increment it by one 
SELECT @x := MAX(id) FROM your_table FOR UPDATE; 

+---------------+ 
| @x := MAX(id) | 
+---------------+ 
|    3 | 
+---------------+ 
1 row in set (0.00 sec) 

FOR UPDATE składnia jest to, co faktycznie stawia blokadę wierszy czytanych przez tego zapytania.

bez wykonania transakcji, zaczynamy kolejną oddzielną sesję (symulacja współbieżne użytkownika), i zrobić to samo:

START TRANSACTION; 

-- // Get the MAX(id) as well 
SELECT MAX(id) FROM demo_table FOR UPDATE; 

Baza będzie czekać, aż blokada ustawiona w poprzedniej sesji jest zwolniony przed uruchomieniem tego pytanie.

Dlatego przejście do poprzedniej sesji, możemy wstawić nowy wiersz i popełnić transakcji:

-- // Insert a new row with id = MAX(id) + 1 
INSERT INTO demo_table VALUES (@x + 1); 

COMMIT; 

po pierwszej sesji zatwierdza transakcję, blokada zostanie zniesione, a zapytanie w drugiej sesji jest zwracana:

+---------+ 
| MAX(id) | 
+---------+ 
|  4 | 
+---------+ 
1 row in set (8.19 sec) 

Należy pamiętać, że bez blokowania, druga sesja byłby wrócił od razu, ale z 3 jak MAX(id) zamiast 4. Jeśli obie sesje miały wstawić wiersz z id z MAX(id) + 1, oba wpisywałyby id = 4. Możesz symulować ten sam test bez wiersza FOR UPDATE, aby zobaczyć, jak to jest obsługiwane bez blokad.

6

Blokowanie może być kluczowe, aby uniknąć dwóch użytkowników modyfikujących dane w tym samym czasie. Możesz myśleć, że jest to mało prawdopodobne, ale w zależności od aplikacji istnieje znaczne ryzyko, jeśli te same dane są często zmieniane przez różnych użytkowników.

Wyobraźmy sobie następującą sytuację bez wykorzystaniem zamków: John otwiera jego ekran (nie wie on przy użyciu bazy danych, jest on tylko użytkownik końcowy, który patrzy na piękną ekranu), modyfikuje niektóre dane, a następnie trafienia "Zapisz". Załóżmy, że John otwiera ekran o 9:30, a następnie zapisuje dane o 9:32.

Jednak Mary otworzyła dokładnie ten sam ekran i ten sam rekord o 9:29. W tym czasie widziała te same dane, które John zrobił o 9:30. Następnie aktualizuje rekord i uderza "Zapisz" o 9:31.

Jakie dane zostały zapisane? John's or Mary's?

Mary z radością pracuje nad kolejnymi płytami, a kiedy wraca później, by ponownie otworzyć płytę, widzi, że jej zmiany zostały utracone, a ona widzi zmiany Johna!

Należy pamiętać, że blokowanie musi być używane mądrze, aby zapobiec nieoczekiwanym skutkom ubocznym. Na przykład, powiedzmy, że twój program blokuje rekord za każdym razem, gdy ktoś go otworzy, dokonuje zmiany. Co stanie się, jeśli John zablokuje rekord i pozostawi ekran sesji otwarty na lunch lub straci połączenie? Blokada może pozostać tam, zablokowana i niezmienna, przez długi czas, zabraniając wszystkim innym zmiany (lub nawet spojrzenia) tego zapisu. Innym czynnikiem może być wydajność, ponieważ czas bazy danych na blokowanie i odblokowywanie rekordów może stać się zauważalny w przypadku dużej liczby transakcji.

Zrozumienie blokady jest kluczowe dla zachowania zadowolenia użytkowników i integralności danych. Proszę spojrzeć na dokumentację.

+0

Dzięki @luiscolorado to naprawdę pomogło :-) – Imran

+0

Wersjonowanie danych byłoby lepszym rozwiązaniem opisanego tu zastosowania. Nie możesz tak naprawdę trzymać blokady przez tak długi czas ... Po zrobieniu zapisywania przez Johna, przeczytania wersji danych +, porównania ich z wyświetlaniem użytkownika, a następnie aktualizacji na danych, które sprawdzają, dla wersji, którą właśnie przeczytałeś dwie minuty temu. Jeśli wersja nie jest taka sama, oznacza to, że ktoś inny dotknął twoich danych - musisz go odświeżyć. – ripper234

+2

@ ripper234: właśnie dlatego powiedziałem, że blokowanie wymaga wielu czynników, aby uzyskać najlepsze podejście. Odpowiadasz za wyjaśniony scenariusz, a twoja sugestia jest dobrze przyjęta. Nie zamierzałem, ani nie byłoby możliwe, przeprowadzić pełnej dyskusji na temat tej koncepcji. Celem było zapewnienie prostej, laikańskiej odpowiedzi. – luiscolorado

Powiązane problemy