2015-01-20 3 views
2

У меня есть небольшой PHP функция на моем сайте, который в основном делает 3 вещи:Простой параллелизм в PHP?

  • проверить, если пользователь вошел в систему
  • если да, проверьте, имеет ли он право делать это действие (DB Select)
  • если да, то смежное действие (DB Insert/Update)

Если у меня есть несколько пользователей, подключенных в то же время на моем сайте, которые пытаются получить доступ к этой конкретной функции, есть ли возможность проблемы параллелизма, например, мы можем иметь в Java например? Я видел несколько примеров о семафоре или встроенной синхронизации PHP, но подходит ли это для этого случая?

Мой PHP код ниже:

if (user is logged) { 
    sql execution : "SELECT....." 
    if(sql select give no results){ 
     sql execution : "INSERT....." 
    }else if(sql select give 1 result){ 
     if(selected column from result is >= 1){ 
      sql execution : "UPDATE....." 
     } 
    }else{ 
     nothing here.... 
    } 
}else{ 
    nothing important here... 
} 
+0

No. MySQL заботится о вас. –

+0

Что это за функция DB? MySql имеет различные механизмы блокировки в зависимости от типа таблицы – Steve

+0

'START TRANSACTION;' – sjagr

ответ

0

Не в PHP. Но у вас могут быть пользователи, вставляющие или обновляющие один и тот же контент. Вы должны сделать shure, этого не произойдет.

Поэтому, если у вас есть они, обновите свой профиль пользователя, к которому пользователь может получить доступ. Никакого столкновения не произойдет.

НО, если они редактируют контент, как в системе управления контентом ... они могут перезаписывать изменения друг друга. Затем вам нужно реализовать механизм блокировки.

Например (есть много способов ...), если вы пишете обновление содержания, содержащего текущее время и пользователя. Тогда у пользователя есть блокировка содержимого, возможно, за 10 минут. Вы должны показать (в данном случае) 10-минутный обратный отсчет во внешнем интерфейсе для пользователя. И кнопку отмены, чтобы разблокировать контент и ... вы, вероятно, получите идею

Если другой человек пытается загрузить контент за эти 10 минут, он получает сообщение об ошибке. «пользователь xy уже ... блокировка истекает через xx: xx»

Надеюсь, это поможет.

+0

вот в чем суть: как убедиться, что пользователи не будут «перемешаны» внутри этой же функции? – theplayer777

+0

отредактировал мой ответ, чтобы уточнить, что «сделать shure это не происходит» часть – snitch182

0

Каждый пользователь, который обращается к вашему сайту, выполняет выделенный процесс PHP. Таким образом, вам не нужны семафоры или что-то в этом роде. Устранение проблем с одновременным доступом - проблема вашей базы данных.

+0

На моем сайте есть три разных кнопки, которые выполняют эту функцию, каждая из которых имеет разные параметры, заданные моему запросу (id). Таким образом, даже если на кнопки тезисов одновременно нажимают 200 человек, нет никаких шансов на то, что проверка безопасности не будет выполнена или параметры моего запроса будут с плохим идентификатором? – theplayer777

+0

Эти 200 человек ОБНОВЛЯЮТ свою собственную строку в таблице БД или все (потенциально) ОБНОВЛЕНИЕ одной и той же строки? Если 200 человек все пытаются ОБНОВИТЬ одну и ту же строку, каково правильное поведение, которое вы ожидаете (сначала это удается, последнее преуспевает, вам все равно, если один из них преуспеет и т. Д.), –

0

В общем, это не безопасно, чтобы решить, следует ли INSERT или UPDATE на основе SELECT результата, так как параллельный процесс PHP может INSERT строку после того, как вы казнены ваш SELECT и не увидели строки в таблице.

Существует два решения. Решение номер один - использовать REPLACE или INSERT ... ON DUPLICATE KEY UPDATE. Эти два типа запросов являются «атомарными» с точки зрения вашего сценария и решают большинство случаев. REPLACE пытается вставить строку, но если она попадает в дубликат, она заменяет конфликтующую существующую строку указанными вами значениями, INSERT ... ON DUPLICATE KEY UPDATE немного сложнее, но используется в аналогичных ситуациях.Смотрите документацию здесь:

http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

http://dev.mysql.com/doc/refman/5.0/en/replace.html

Например, если у вас есть таблица product_descriptions, и вы хотите, чтобы вставить продукт с ID = 5 и некоторым описанием, но если продукт с ID 5 уже существует, вы хотите обновить описание, то вы можете просто выполнить следующий запрос (при условии, что есть UNIQUE или PRIMARY ключ на ID):

REPLACE INTO product_description (ID, description) VALUES(5, 'some description') 

Он добавит новую строку с идентификатором 5, если она еще не существует, или обновит существующую строку с идентификатором 5, если она уже существует, что, вероятно, именно то, что вы хотите.

Если это не так, то подход номер два заключается в использовании блокировки, например, так:

query('LOCK TABLE users WRITE') 
if (num_rows('SELECT * FROM users WHERE ...')) { 
     query('UPDATE users ...'); 
} 
else { 
     query('INSERT INTO users ...'); 
} 
query('UNLOCK TABLES') 
Смежные вопросы