Всем доброго времени суток. Искал информацию в гугле. Информации вроде много - в голове каша. Исходные данные: 1)Таблица innoDB 2) Мне нужно, чтоб при UPDATE была блокировка такого рода, что пока этот UPDATE не завершится - другой пользователь не сможет ни прочитать данные из этой строки, ни изменить. $updatov = mysql_query("UPDATE `tovar` SET `tsena` = 'tsena' + 1 WHERE `tov` = 'mon' "); Я не совсем понимаю нужно ли вообще что-то дописывать, чтоб блокировалось. Просто необходимо, чтоб, если 5 пользователей одновременно обратятся к этому запросу, чтоб `tsena` стала именно +1+1+1+1+1, то есть +5 в общем.
Нет, не нужно, если это одна операция, то база сама все сделает. Добавлено спустя 53 секунды: Блокировка только этой строки
Код (PHP): $updatov = mysql_query("UPDATE `tovar` SET `tsena` = 'tsena' + 1 WHERE `tov` = 'mon' "); Кавычки неправильные (вокруг tsena справо от знака равенства). Надо в обоих случаях косые. Код (PHP): $updatov = mysql_query("UPDATE `tovar` SET `tsena` = `tsena` + 1 WHERE `tov` = 'mon' ");
Спасибо ребят! А если операции 2-3? Если например человек попробует совершить 2 операции влияющие на 1 строку одновременно на 2 компьютерах? К примеру одно действие отвечает за покупку, второе за продажу. Обе влияют на его баланс. Если он на 2 компах одновременно ткнёт купить/продать. Сработает ли всё как надо или может не среагировать на одно из действий? Чтоб понятнее было 1 случай Код (Text): $update_userbal = mysql_query("UPDATE `users` SET `baltot` = `baltot` + '".$sellcost." WHERE `usernume` = '".$ushar_ex['usernume']."'"); 2 случай Код (Text): $update_userbal2 = mysql_query("UPDATE `users` SET `baltot` = `baltot` - '".$round."' WHERE `usernume` = '".$ushar_ex['usernume']."'"); Спасибо) я просто изменял параметры, чтоб меньше код получился и случайно описАлся.
По идее, действия совершатся последовательно, в соответствии с тем, в какой последовательности были запрошены.
То есть 99.9% что мои опасения можно исключить? Вопрос просто в деньгах (хоть и не моих; - пользователей), но всёже не хотелось, чтоб какой-то умник воспользовался. А умники всегда находятся
До тех пор, пока ваш скрипт для достижения цели будет использовать только один запрос - проблем не будет. Как только вы захотите использовать два и более, например sql: select `baltot`... php: $baltot += 100500; sql: update ... `baltot` = $baltot то нужно использовать транзакцию или другие механизмы (например, select for update).
Это на 100%. Как заметил MiksIr, под выражением "несколько операций" подразумевается несколько запросов, которые должны обработаться по-очереди, без вклинивания лишних между ними. Тогда надо делать ручную блокировку или транзакцию. Более того, InnoDB в транзацию неявно оборачивает каждый запрос, поэтому конфликты совершеннно исключены.
Я понял. значит не совсем верно задал вопрос изначально. Запросов идет несколько: Код (Text): $coinsell = ($ushar_exgold-1); $update_coin = mysql_query("UPDATE `users` SET `coinsell` = `coinsell` + 1 WHERE `usernume` = '".$admin_saitului."'"); $update_userbal = mysql_query("UPDATE `users` SET `baltot` = `baltot` + '".$sellcost."', `coinsell` = `coinsell` + 1 WHERE `usernume` = '".$ushar_ex['usernume']."'"); $curmon = ($ushar_exbal+$sellcost); $cerereSQL = "INSERT INTO `history` (`action`, `amount`, `userid`, `curcoin`, `curbal`, `time`, `date`, `user`, `cost`, `soldfor`) VALUES ('sellgold', '1', '".$ushar_ex['id']."', '".$coinsell."', '".$curmon."', NOW(), CURDATE(), '".$ushar_ex['usernume']."', '".$cost."', '".$sellcost."')"; mysql_query($cerereSQL); Как обезопаситься от вклинивания?
В самом начале выполнить START TRANSACTION и в самом конце COMMIT для данного примера это будет достаточно http://ru.wikipedia.org/wiki/%D0%A3%D1%80%D0%BE%D0%B2%D0%B5 ... 0%B8%D0%B9 http://www.intuit.ru/department/database/sql/16/1.html