JSON — PHP несколько запросов одновременно создают неправильные записи базы данных

Я запускаю графический файловый менеджер, похожий на OneDrive, OpenCloud или что-то в этом роде. Файлы, папки, учетные записи и основные настройки сервера хранятся в базе данных как объекты в кодировке JSON (да, я избавился от столбцов в пользу json). Проблема заключается в том, что несколько запросов используют один и тот же объект одновременно, поэтому часто сохраняются неверные данные, поскольку запросы, очевидно, не могут передавать изменения друг другу.

Например, когда кто-то начинает загрузку, он загружает объект учетной записи владельца этого файла, увеличивает его счетчик пропускной способности, а затем кодирует / сохраняет его обратно в БД в конце загрузки. Но, скажем, если у меня будет 3 загрузки одного и того же файла одновременно, они все загрузят один и тот же объект учетной записи, изменят данные по своему усмотрению и сохранят свои данные без учета других, которые перекрываются. В этом случае 3 загрузки будут показаны как 1.

Помимо того, что загрузка и пропускная способность не учитываются, у меня также есть проблема, когда я пытаюсь создать функцию обслуживания, которая загружает объект сервера и не сохраняет его в течение потенциально нескольких минут — это, очевидно, не будет работать, пока Тем временем происходит загрузка и манипулирование объектом сервера, потому что все это будет просто перезаписано старыми данными после завершения функции обслуживания.

По сути, это проблема с многопоточностью. Я изучил PHP APC в надежде, что смогу сохранить объекты глобально между потоками, но это не работает, поскольку он просто сериализует / десериализует данные для каждого запроса, а не фактически указывает на то, что каждый запрос указывает на объект в памяти.

Я абсолютно не представляю, как это исправить, не спроектировав совершенно новую систему, которая будет совершенно другой … это отстой.

Любые идеи о том, как я должен поступить об этом, были бы великолепны.

Спасибо!

0

Решение

Это не проблема потоков. Ваша база данных не соответствует ни одному из стандартов построения баз данных, включая даже первую нормальную форму: каждая ячейка должна содержать только одно значение. Когда вы храните данные JSON в БД, вы не можете написать запрос SQL, чтобы сделать эту транзакцию атомарной. Так что да, ты необходимость положить этот код в мусорное ведро.

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

1

Другие решения

Вы можете попробовать использовать flock, я думаю, у вас уже есть идентификатор пользователя до получения JSON из БД.

$lockfile = "/tmp/userlocks/$userid.txt";
$fp = fopen($lockfile, "w+");
if (flock($fp, LOCK_EX)) {
//Do your JSON update

flock($fp, LOCK_UN); //unlock
}else{
// lock exist
}

Вам нужно выяснить, что делать при блокировке, возможно, подождите 0,5 секунды и попытаться снова получить блокировку, или отправьте сообщение «Одновременно разрешена только одна загрузка» или …

-1

По вопросам рекламы [email protected]