Здравствуйте, у меня возникла проблема, и я чето не знаю как ее решить. Дело в том, что на моем сайте (файлообменник) при загрузке нового файла выбирается специальное имя чтобы его сохранить. Делается это следующим образом: есть таблица с инфой о файлах, в ней Code: fid not null auto_increment primary key, nname varchar (50) .... ..... прочая инфа .... .... При начале загрузки нового файла, выбирается максимальное значение fid, и _сразу же_ создается новая запись где fid автоинкремент, а nname=максимальный до этого fid+1. далее идут всякие вычисления, которые занимают много времени, а потом созданная в таблице запись просто UPDATEится, зная какое nname выбрано. Немного путанно объяснил, код кусок кода: Code: //смотрим сколько файлов и выбираем их количество для создания имени $stmt=$link->prepare("SELECT fid+1 FROM MYFILES ORDER BY fid DESC LIMIT 1"); $stmt->bind_result($newcount); $stmt->execute(); $stmt->fetch(); $stmt->close(); $prestatus='prepare'; //сразу забиваем имя под новый файл с пустой инфой и статусом "deleted" $stmt=$link->prepare("INSERT INTO MYFILES(nname,status) VALUES(?,?)"); $stmt->bind_param("ss", $newcount,$prestatus); $stmt->execute(); $stmt->close(); echo("Место под файл занято: $newcount"); .......... .......... тут всякие вычисления, об их скорости можно не заботиться, т.к. место уже "забито" .......... .......... //если все удачно прошло - дописываем инфу в забитую ячейку $status='normal'; $stmt=$link->prepare("UPDATE MYFILES SET всякиезначения=?,.....................,status=? WHERE (nname=?)"); $stmt->bind_param("......",........,$status,$nname); $stmt->execute(); $stmt->close(); Казалось бы, все сделано качественно. Но седня сканил акуниксом, так он мне файлы быстро-быстро грузил...и потом я заметил несколько записей в БД с разными FID но одинаковыми NNAME Вообще не понял как такое могло быть и как от этого избавляться. Разве что еще короче написать первые два запроса (найти и забить новые значения). Но этош пипец.... Короче я расстроен... посоветуйте ченить, может я что-то не замечаю (сонный уже, 4 утра)? оО
Apeckou Да, возможен race condition между PHP: $stmt=$link->prepare("SELECT fid+1 FROM MYFILES ORDER BY fid DESC LIMIT 1"); //и $stmt=$link->prepare("INSERT INTO MYFILES(nname,status) VALUES(?,?)"); Правильно делать так: PHP: $stmt=$link->prepare("INSERT INTO MYFILES(nname,status) VALUES(?,?)"); $stmt->bind_param("ss", $newcount,$prestatus); $stmt->execute(); $fid = $stmt->insert_id; // Здесь будет fid новой записи. $stmt->close(); Плюс PHP: $stmt=$link->prepare("UPDATE MYFILES SET всякиезначения=?,.....................,status=? WHERE (nname=?)"); $stmt->bind_param("......",........,$status,$nname); Следует заменить на PHP: $stmt=$link->prepare("UPDATE MYFILES SET всякиезначения=?,.....................,status=? WHERE (fid=?)"); $stmt->bind_param("......",........,$status,$fid); База гарантирует только уникальность fid, а не уникальность nname (если только вы не повесили уникальный индекс на столбец).
Крутяк, добавил плюсиков скока мог, завтра буду переделывать!) я вот щас сижу и думаю, нафига я вообще этот nname ввел.. щас уже не помню, но чето он мне перестал нравиться резко а переделывать слишком много всего, чтобы от него избавиться(