Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zapobiegaj jednoczesnym transakcjom w aplikacji internetowej

Cieszę się, że zdajesz sobie sprawę, że jest to tylko złe i tymczasowe rozwiązanie i powinieneś zoptymalizować swój kod. Zapomnij o swoich tokenach i innych rzeczach. Najłatwiejszym i nadal skutecznym sposobem jest prawdopodobnie wyłączna blokada pliku na współdzielonym pliku na operację. Możesz sobie to wyobrazić jak kawałek drewna i tylko jeden może trzymać identyfikator i tylko ten, kto go trzyma, może mówić lub coś robić.

<?php
    $fp = fopen("/tmp/only-one-bed-available.txt", "w+");

    if (flock($fp, LOCK_EX)) { // do an exclusive lock

         // do some very important critical stuff here which must not be interrupted:
         // sleeping.
         sleep(60);
         echo "I now slept 60 seconds";
        flock($fp, LOCK_UN); // release the lock
    } else {
        echo "Couldn't get the lock!";
    }

    fclose($fp);
?>

Jeśli wykonasz ten skrypt 10 razy równolegle, ukończenie zajmie 10 minut (ponieważ dostępne jest tylko jedno łóżko!) i zobaczysz echo "Teraz spałem..." co 60 sekund (w przybliżeniu).

To serializuje WSZYSTKIE wykonania tego kodu GLOBALNIE. To prawdopodobnie nie jest to, czego chcesz (chcesz to dla każdego użytkownika, prawda?) Jestem pewien, że masz coś takiego jak User-ID, w przeciwnym razie użyj obcego adresu IP i mieć unikalną nazwę pliku dla każdego użytkownika:

Możesz także zdefiniować nazwę pliku blokady dla grupy operacji. Może użytkownik może robić kilka rzeczy równolegle, ale tylko ta operacja sprawia problemy? Nadaj mu tag i umieść go w nazwie pliku blokady!

Ta praktyka naprawdę nie jest taka zła i można ją wykorzystać! Niewiele jest sposobów, aby zrobić to szybciej (wewnętrzne elementy mysql, segmenty pamięci współdzielonej, serializacja na wyższej warstwie, np. Load Balancer...)

Z rozwiązaniem przedstawionym powyżej możesz to zrobić w swojej aplikacji, co prawdopodobnie jest dobre. Możesz użyć tego samego schematu również w Mysql:http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock

Ale implementacja PHP jest prawdopodobnie łatwiejsza i lepsza dla twojego przypadku użycia.

Jeśli naprawdę chcesz mieć jeszcze bardziej eleganckie rozwiązanie, sprawdź tę funkcję http://www.php.net/manual/en/function.sem-get.php



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak uruchomić serwer MySQL po aktualizacji OSX Yosemite?

  2. Zamiennik mysql_num_rows polecić?

  3. MySQL ERROR 1005:Nie można utworzyć tabeli (errno:150)

  4. Używanie JDeveloper z bazą danych MySQL i bazą danych Oracle na AWS RDS, część 3

  5. Usuwanie zduplikowanych rekordów SQL, aby umożliwić unikalny klucz