Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Zabezpieczenie przed podwójnym pobraniem rekordu
dav
post 20.08.2013, 14:58:50
Post #1





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 20.08.2013

Ostrzeżenie: (0%)
-----


Chcę pobrać jeden losowy wiersz z tabeli. Robię to za pomocą 2 skryptów, odpalanych w tym samym czasie.
Jak zabezpieczyć się przed tym, aby rekord nie został pobrany przez oba te skrypty, ale tylko przez jeden ?
Wiem że mogę sobie odpowiednio oflagować rekord, ale jeśli drugi skrypt odpali się kilka milisekund później to jest możliwość że też zdąży go pobrać zanim ten pierwszy go oflaguje.
Czy transakcje rozwiążą problem, czy należy zastosować blokownie tabel?
Go to the top of the page
+Quote Post
PHP_Addicted
post 20.08.2013, 15:32:39
Post #2





Grupa: Zarejestrowani
Postów: 31
Pomógł: 2
Dołączył: 14.12.2011

Ostrzeżenie: (0%)
-----


Pierwsze co mi przychodzi do głowy to właśnie lock na tabele.

http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html
Go to the top of the page
+Quote Post
dav
post 20.08.2013, 17:01:22
Post #3





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 20.08.2013

Ostrzeżenie: (0%)
-----


ok, a co w przypadku większej ilości skryptów odpytujących?
Owszem wspomniałem o dwóch, ale docelowo ma być ich kilkanaście.
Jeśli wszystkie wystartują w tym samym czasie i każdy z nich będzie blokować tabele, chyba nie za dobrze wpłynie to na szybkość działania.
Chociaż może, przy tych ilościach to nie będzie mieć jeszcze takiego znaczenia. Jak sądzicie?
Go to the top of the page
+Quote Post
Pyton_000
post 21.08.2013, 19:30:18
Post #4





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


A czy ten wiersz ma wracać z powrotem no póli dostępnych? Jak to jest?

Bo możesz robić np.
UPDATE flaga+1;
SELECT * ... WHERE Flaga = 1;

Minusem jest non stop update;

Ew. jeżeli baza stoi na InnoDB to transakcja na ww. zapytania tylko w odwrotnej kolejności czyli najpierw select, potem insert.
InnoDB ma blokadę wiersza, a w połączeniu z transakcją gwarantuje zabezpieczenie przed pobraniem go.
Go to the top of the page
+Quote Post
sazian
post 21.08.2013, 20:14:50
Post #5





Grupa: Zarejestrowani
Postów: 1 043
Pomógł: 141
Dołączył: 19.09.2006
Skąd: B-tów

Ostrzeżenie: (0%)
-----


jedyne sensowne rozwiązanie to blokowanie tabel, przy kilku tysiącach skryptów może zauważysz spowolnienie

czyli robisz tak
lock
SELECT ....
UPDATE flaga=1 where ....
unlock

a jeszcze lepiej jeśli uda się to wepchnąć do funkcji mysql'a


edit:
myisam zakłada blokadę na całą tabelę przy każdym insert/update... a jakoś większość ludzi tego nawet nie zauważa, więc jeśli ręcznie zablokujesz blokadę to i tak większej różnicy nie będzie

Ten post edytował sazian 21.08.2013, 20:20:08
Go to the top of the page
+Quote Post
dav
post 25.08.2013, 22:00:25
Post #6





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 20.08.2013

Ostrzeżenie: (0%)
-----


Dzięki za odpowiedź.

Jest tylko problem bo jesli zrobie tak:

lock table devices read;

SELECT ....
UPDATE ....

UNLOCK TABLES;

To wtedy nie chce zrobić update'a, gdyż tabela jest zablokowna.
W takim razie transakcje?
Go to the top of the page
+Quote Post
irmidjusz
post 25.08.2013, 22:16:28
Post #7





Grupa: Zarejestrowani
Postów: 279
Pomógł: 60
Dołączył: 25.02.2012

Ostrzeżenie: (0%)
-----


Jeśli transakcje, to serialized, a lock typu write musi być...

Ten post edytował irmidjusz 25.08.2013, 22:17:31


--------------------
there is much to be learned
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 18.04.2024 - 12:32