2012-09-26 3 views
5

Używam blokowania wierszy (transakcje) w MySQL do tworzenia kolejki zadań. Zastosowany silnik to InnoDB.Wady blokowania wiersza MySQL

zapytań SQL

START TRANSACTION; 
SELECT * 
FROM mytable 
WHERE status IS NULL 
ORDER BY timestamp DESC LIMIT 1 
FOR UPDATE; 
UPDATE mytable SET status = 1; 
COMMIT; 

Według tego webpage,

The problem with SELECT FOR UPDATE is that it usually creates a single synchronization point for all of the worker processes, and you see a lot of processes waiting for the locks to be released with COMMIT.

Pytanie: Czy to oznacza, że ​​kiedy pierwszy kwerenda jest wykonywana, który trwa trochę czasu, aby dokończyć th e transakcji przed, gdy drugie podobne zapytanie występuje przed zatwierdzeniem pierwszej transakcji, będzie musiał czekać na zakończenie jej przed wykonaniem zapytania? Jeśli to prawda, to nie rozumiem, dlaczego blokowanie wiersza w jednym wierszu (co zakładam) wpłynie na następne zapytanie o transakcję, które nie wymagałoby odczytania zablokowanego wiersza?

Dodatkowo, czy ten problem można rozwiązać (i nadal uzyskuje się blokowanie wiersza efektu dla kolejki zadań), wykonując UPDATE zamiast transakcji?

UPDATE mytable SET status = 1 
WHERE status IS NULL 
ORDER BY timestamp DESC 
LIMIT 1 
+0

Blokowanie opiera się na silniku pamięci masowej - z czego korzystasz? –

+0

Edytowano post, jego InnoDB – Nyxynyx

+0

Dzięki (i 9 dodatkowych znaków, aby przejść) –

Odpowiedz

1

Jeśli używasz do UPDATE z silnikiem przechowywania, który używa blokad stron lub wierszy, wiersze badane przez zapytanie są zablokowane do zapisu do końca bieżącej transakcji. Użycie LOCK IN SHARE MODE ustawia wspólną blokadę, która pozwala innym transakcjom na odczyt badanych wierszy, ale nie na nich. io tym zapytaniu

UPDATE mytable SET status = 1 
WHERE status IS NULL 
ORDER BY timestamp DESC 
LIMIT 1 

od InnoDB

automatycznie nabyć zamki podczas przetwarzania instrukcji SQL myślę, że pracuje jako takie same.