Clicky

Skocz do zawartości


Zdjęcie
- - - - -

SELECT z ORDER BY dla tabeli z bardzo szybko zmieniającą się zawartością

2 odpowiedzi w tym temacie
select mysql

  • Zaloguj się, aby dodać odpowiedź

#1 pavel

pavel

    Początkujący

  • Użytkownik
  • Pip
  • 14 postów

Napisano 29 wrzesień 2013 - 12:54

Temat brzmi dość zagadkowo, ale nie miałem pomysłu jak go lepiej nazwać. Sytuacja wygląda następująco - mamy (uproszczoną dla celów dydaktycznych :)) tabelę w MySQL:

 

  • id (INT)
  • name (VARCHAR)
  • info (VARCHAR)
  • lastmod (DATETIME)
  • locked (DATETIME)

 

 

Jedno żądanie polega na wybraniu 1 rekordu z bazy (order by lasmod ASC LIMIT 1) i wykonaniu na nim pewnej operacji, która może trwać od 0.5 - 3 sekundy, po czym czas w kolumnie lastmod jest zmieniany na aktualny - więc rekord spada na koniec kolejki. Problem polega na tym, że żądań może być momentami bardzo wiele - nawet kilka na sekundę (a może jeszcze częściej) i gdy nie wybieramy rekordu losowo może się zdarzyć sytuacja w której w kolejnym żądaniu wybierzemy rekord, który jest przetwarzany w żądaniu poprzednim.

 

Wydawało mi się, że wystarczy w zapytaniu wybierającym rekord dodać warunek omijający aktualnie przetwarzane rekordy w stylu:

WHERE locked > NOW() - INTERVAL 10 MINUTE 

i po wybraniu rekordu wykonać zapytanie ustawiające blokadę:

UPDATE tabela SET locked=NOW() WHERE id={ID_WYLOSOWANEGO_REKORDU}

To oczywiście w dużej mierze poprawiło stan rzeczy, natomiast bardzo sporadycznie zdarzają się sytuacje, w których między wybraniem rekordu a ustawieniem blokady wiersz zostanie wybrany raz jeszcze w drugim żądaniu w wyniku czego będzie przetwarzany w 2 wątkach jednocześnie.

 

Pytanie jak temu zaradzić - czy istnieje jakiś inny sposób zablokowania wiersza?

 

 



#2 Daredzik

Daredzik

    Młodszy Mastah

  • Użytkownik
  • PipPip
  • 308 postów
  • Skąd:Pszczyna

Napisano 29 wrzesień 2013 - 21:44

http://dev.mysql.com...x-isolevel.html



#3 lukaskolista

lukaskolista

    Młodszy Mastah

  • Użytkownik
  • PipPip
  • 414 postów

Napisano 03 październik 2013 - 21:32

Dlatego MySQL ssie, w PostgreSQL moznaby bylo zrobic to tak:

UPDATE tabela SET lastmod = NOW() ORDER BY lastmod LIMIT 1 RETURNING *;

ktore to zapytanie zwrociloby Ci rekord tak jak select + update w MySQL







Również z jednym lub większą ilością słów kluczowych: select, mysql

Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych