2012-12-29 28 views
5

Wykonuję webservice w PHP, który wykonuje serię obliczeń na podstawie wyboru z tabeli, a następnie aktualizuje tabelę z nowymi wynikami.Blokada stołu MySql w PHP

Jednak chcę zapobiec przypadkowi, w którym inna osoba nawiązuje połączenie z tym samym serwisem internetowym, podczas gdy sesja innej osoby wciąż wykonuje aktualizację.

Czy to jest właściwe, aby zablokować cały stół, a następnie odblokować go ponownie? Jeśli tak, jak mogę zablokować i odblokować tabelę mysql przy użyciu PHP pdo?

+0

Nie jest to bezpośrednia odpowiedź, ale nie sądzę, że to żaden problem. Obliczenia i pobieranie danych z bazy danych odbywa się w ciągu kilku milisekund. Szanse lub dwie osoby wchodzące w interakcje w tym samym czasie są tak małe, że większość ludzi nie zadaje sobie takiego blokady. – OptimusCrime

+0

Zdaję sobie z tego sprawę. Nie jestem jednak skłonny do podejmowania ryzyka, ponieważ uszkodzenie danych może mieć poważne konsekwencje dla mojego wniosku. – user1574041

+0

Chcesz użyć [transakcji bazy danych] (http://dev.mysql.com/doc/en/sql-syntax-transactions.html), aby zapewnić atomowość operacji. – eggyal

Odpowiedz

0

Zamieściłem komentarz:

Nie bezpośrednia odpowiedź, ale nie sądzę, że to jest jakiś problem. Obliczenia i pobieranie danych z bazy danych odbywa się w ciągu kilku kolejnych milisekund. Szanse lub dwie osoby wchodzące w interakcję w tym samym czasie są tak małe, że większość ludzi nie zadaje sobie takiego zamka.

Ale jeśli te obliczenia są krytyczne można uniknąć tego problemu poprzez dodanie nowego pola i po prostu nazwać occupied, busy lub coś podobnego.

Po uruchomieniu skryptu sprawdź, czy to pole jest ustawione na wartość 1, jeśli tak, ustaw skrypt na 1-2-3 sekundy, a następnie spróbuj ponownie. Jeśli to pole jest ustawione na 0, zaktualizuj je do 1, wykonaj obliczenia i ponownie ustaw je na 0.

To uniemożliwiłoby dwóm osobom dostęp do tych samych wartości w tym samym czasie.

+0

Problem z tym podejściem polega na tym, że jeśli obaj klienci odczytują wartość pola wyboru, zanim je zaktualizuje, obaj będą myśleć, że mogą kontynuować. Potrzeba CPU do wykonywania operacji * atomowo * w celu zapewnienia bezpieczeństwa w aplikacjach współbieżnych: systemy operacyjne udostępniają do tego API, a RDBMS wywołuje to API w implementacji mechanizmów blokujących. ** Nie próbuj budować tego sam **, ponieważ jest skazany na niepowodzenie. Zamiast tego użyj atomowości zapewnianej przez transakcje bazy danych: po to są. – eggyal

+0

Wydaje się, że najbezpieczniej jest wdrożyć rozwiązanie, na które jestem gotowy. Czy istnieje jakieś możliwe rozwiązanie, które zapobiegnie wspomnianiu o jaju? – user1574041

+0

@eggyal: Przeczytaj drugą odpowiedź opublikowaną tutaj. Nie jest możliwe, aby dwoje ludzi miało do niego dostęp w tym samym czasie. Robi się to zbyt szybko, aby to się stało. – OptimusCrime

3

Systemy zarządzania bazami danych, takie jak MySQL, są na tyle inteligentne, aby zapobiegać naruszeniom współbieżności, takim jak te.

Poszukaj poziomów izolacji bazy danych (odczytuj niezaakceptowane, przeczytaj zatwierdzone, powtarzalne czytanie, szeregowalne) i możliwe problemy (brudny odczyt, nieodwracalny odczyt ...) ->Wikipedia.

Osobiście nie polecam blokady stołu w twoim przypadku. Lepiej zawiń swoje obliczenia i operacje bazy danych w transakcji i polegaj na DBMS, aby zarządzać swoimi rzeczami.

+0

Jednak robię to teraz: 1) Dokonaj wyboru na moim stole 2) Wykonaj moje obliczenia w PHP na podstawie tego wybierz 3) Zaktualizuj tabelę na podstawie obliczeń PHP. Czy to możliwe w transakcji? Jestem stosunkowo nowy w bazach danych. – user1574041

+1

@ user1574041: Możesz użyć odczytu blokującego (http://dev.mysql.com/doc/en/innodb-locking-reads.html), takiego jak 'WYBIERZ ... DO AKTUALIZACJI '. Jednak możesz również zauważyć, że możesz przenieść logikę obliczeń z PHP i na SQL, tak, że jest wykonywana w jednej instrukcji 'UPDATE', np. 'UPDATE myTable SET myColumn = (1 + myColumn) * 2 GDZIE ...'. – eggyal

+0

Dzięki @eggyal, również będę moją rekomendacją. Jeśli zdecydujesz, że musisz wykonać obliczenia w php i nie chcesz zablokować całej tabeli, możesz spojrzeć na mechanizm blokowania bazy plików, taki jak: flock: http://php.net/manual/en/ function.flock.php –