Я сталкиваюсь со следующей проблемой:
function book($memberid, $classid){
if (!book){
// update the db and change the book variable to true
}
}
Моя проблема заключается в том, что одновременно отправлено 2 запроса. Первый запрос передает строку if (! Book) {но еще не обновляет db. И в то же время второй запрос выполняет ту же функцию, а также передает строку if (! Book) {. Следовательно, результат неправильный.
Я хочу знать, как решить эту проблему concurrency. Заблокировать db? Но я боюсь, что это повлияет на производительность.
Зачем вам нужна эта переменная?
Стандартный способ решения проблем concurrency при обновлении баз данных - позволить базе данных обрабатывать его посредством транзакций (что в некоторых случаях будет влиять на производительность, но это будет только решение для кода).
Я хотел бы видеть, что входит в предложение if (! book).
EDIT: Почему бы вам не изменить db, чтобы комбинация (личность, класс) была уникальной? Таким образом, вы просто физически не можете вставить в два раза то же значение в таблице. Я все еще принимаю дикие догадки, потому что это зависит от структуры базы данных. Кроме того, MySQL имеет специальный синтаксис, чтобы сделать условную вставку, которая устраивает здесь. Проверьте этот url.
Можете ли вы использовать
UPDATE x SET y WHERE z
затем просто проверить затронутые строки, чтобы увидеть, что-нибудь изменилось? Таким образом, MYSQL эффективно выполняет как проверку, так и фактическое изменение данных в одной гладкой атомной транзакции для вас без проблем concurrency. (Я основываю это на том факте, что вы используете слово "обновление", а не "вставляете" в свой Q, а если вставить этот подход не будет работать, но VolkerK будет)
Если вы действительно должны проверить SELECT, тогда напишите UPDATE как два отдельных оператора, тогда транзакции - единственный путь. Вы упоминаете о блокировке БД - обратите внимание, что это не единственный доступный вам вариант. Если вы используете таблицы InnoDB, вы можете использовать разные уровни.
Если вы создаете уникальный индекс (человек, класс), вы можете просто попробовать вставить новую запись без каких-либо предыдущих тэгов. Если в записи (person, class) есть еще одна запись с одинаковыми значениями, новая запись будет отклонена, а MySQL добавит "duplicate key" error который может быть соответствующим образом обработан вашим script:
if ( 1062===mysql_errno() ) { echo "you've already made a reservation for this lecture."; }