Mysql
 sql >> база данни >  >> RDS >> Mysql

Предотвратяване на едновременни транзакции в уеб приложение

Радвам се, че осъзнаваш, че това е само лошо и временно решение и трябва да оптимизираш кода си. Забравете вашите токени и други неща. Най-лесният и все пак ефикасен начин вероятно е да имате ексклузивно заключване на споделен файл за всяка операция. Можете да си представите това като парче дърво и само един може да държи документ за самоличност и само който го държи има право да говори или да прави нещо.

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

Ако изпълните този скрипт 10 пъти паралелно, ще отнеме 10 минути, за да завърши (тъй като има само едно свободно легло!) и ще видите ехото „Сега спах...“ на всеки 60 секунди (приблизително).

Това сериализира ВСИЧКИ изпълнения на този код ГЛОБАЛНО. Това вероятно не е това, което искате (искате го на базата на потребител, нали?) Сигурен съм, че имате нещо като User-IDs, в противен случай използвайте чуждия IP-адрес и имат уникално файлово име за всеки потребител:

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

Можете също така да дефинирате име на файл за заключване за група от операции. Може би потребителят може да прави някои неща паралелно, но само тази операция създава проблеми? Дайте му етикет и го включете в името на заключващия файл!

Тази практика наистина не е толкова лоша и може да се използва! Има само малко начини да го направите по-бързо (вътрешни елементи на mysql, споделени сегменти на паметта, сериализиране на по-висок слой като балансиращо натоварване...)

С публикуваното по-горе решение можете да го направите във вашето приложение, което вероятно е добре. Можете да използвате същата схема и в Mysql:http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock

Но внедряването на PHP вероятно е по-лесно и по-добро за вашия случай на употреба.

Ако наистина искате да ритате още по-елегантно решение, просто вижте тази функция 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. Функция MySQL ACOS() – Връща косинус на дъгата на число

  2. Как да съпоставя времеви печат в хибернация към MySQL BIGINT?

  3. Как да съхранявам подробности за twitter oauth в базата данни на mysql?

  4. Кой е най-добрият набор от знаци за полето за имейл?

  5. Проблеми при увеличаване на поле в MySQL/PHP с подготвени изрази