sql >> Database >  >> RDS >> Mysql

Voorkom gelijktijdige transacties in een webapplicatie

Ik ben blij dat je je realiseert dat het slechts een slechte en tijdelijke oplossing is en dat je je code moet optimaliseren. Vergeet je tokens en zo. De gemakkelijkste en nog steeds efficiënte manier is waarschijnlijk om een ​​exclusieve bestandsvergrendeling op een gedeeld bestand per bewerking te hebben. Je kunt je dit voorstellen als een stuk hout en er kan er maar één een identiteitsbewijs vasthouden en alleen wie het vasthoudt mag praten of iets doen.

<?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);
?>

Als je dit script 10 keer parallel uitvoert, duurt het 10 minuten om te voltooien (omdat er maar één bed beschikbaar is!) en zie je de echo "Ik sliep nu..." elke 60 seconden (ongeveer).

Dit serialiseert ALLE uitvoeringen van deze code GLOBAAL. Dit is waarschijnlijk niet wat je wilt (je wilt het per gebruiker, nietwaar?) Ik weet zeker dat je zoiets als gebruikers-ID's hebt, gebruik anders het buitenlandse IP-adres , en hebben een unieke bestandsnaam voor elke gebruiker:

<?php $fp = fopen("/tmp/lock-".$_SERVER["REMOTE_ADDR"].".txt", "w+"); ?>

U kunt ook een vergrendelingsbestandsnaam definiëren voor een groep bewerkingen. Misschien kan de gebruiker wat dingen parallel doen, maar alleen deze operatie levert problemen op? Geef het een tag en neem het op in de bestandsnaam van het slot!

Deze oefening is echt niet zo slecht en kan worden gebruikt! Er zijn maar kleine manieren om het sneller te doen (mysql internals, gedeelde geheugensegmenten, serialisatie op een hogere laag zoals load balancer...)

Met de hierboven geposte oplossing kun je het in je applicatie doen, wat waarschijnlijk goed is. Je kunt hetzelfde schema ook in Mysql gebruiken:http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock

Maar de PHP-implementatie is waarschijnlijk gemakkelijker en beter voor uw gebruik.

Als je echt een nog elegantere oplossing wilt, kijk dan eens naar deze functie http://www.php.net/manual/en/function.sem-get.php



  1. Oracle REGEX_SUBSTR houdt geen rekening met null-waarden

  2. Trek maanden af ​​van de huidige datum sql

  3. Wat is de gemaakte datum-tijd voor tabelrij in Oracle?

  4. mysql duurt te lang om rijen in te voegen