Менеджер сущностей Doctrine и база данных с несколькими потоками - PullRequest
2 голосов
/ 28 февраля 2012

В настоящее время у меня есть запрос XHR, который может сработать N раз от клиента. Эти запросы обрабатываются сервером, и каждый запрос обычно создает новую строку в базе данных (все doctrine / xml).

Прежде чем я сохраню () объект, я проверяю, есть ли у него уникальное имя файла (я загружаю ресурсы), и делаю это, переопределяя функцию persist (), вызывая мой метод getUniqueFilename (), а затем вызывая parent :: persist.

Я получаю состояние гонки, когда выполняю несколько запросов XHR с одним и тем же именем файла. Что произойдет, если несколько потоков будут запущены в одно и то же время и проверят базу данных на наличие дубликатов, чтобы сгенерировать уникальное имя файла.

  • Загрузить файл
  • Проверить базу данных, если имя файла существует
  • Увеличение имени файла (например, filename_1)

Однако, когда несколько запросов XHR происходят в нескольких потоках, возникает состояние гонки, когда несколько файлов вставляются в базу данных с одним и тем же именем (имя_файла_1 генерируется несколько раз).

Я думаю, что способ решить это либо

  • MySQL триггер
  • Добавление в таблицу уникального ограничения для имени файла и включение в код try / catch в коде

Что бы вы сделали?

Ответы [ 2 ]

4 голосов
/ 28 февраля 2012

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

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

2 голосов
/ 28 февраля 2012

Я бы предложил использовать другую стратегию: использование mysql auto_increment для получения идентификатора, сохранение актива в базе данных, получение идентификатора и добавление его к имени файла.Все остальные способы имеют недостатки, в которых необходимо выполнять частичные откаты, обрабатывать повторяющиеся имена файлов и т. Д.

Я бы также предложил не использовать исходное имя файла для хранения объекта: вы сталкиваетесь с проблемами с запрещенными символами на разных операциях.системы, а также кодировка символов, возможно, по какой-либо причине дублируются (например, потому что база данных чувствительна к регистру, а файловая система - нет).Могут быть и другие недостатки, такие как максимальная длина имени файла, или такие, о которых вы можете не знать прямо сейчас.

Мое решение заключается в простом использовании автоматического увеличения mysql в качестве имени файла.Если вы думаете об этом, это имеет смысл.Автоинкремент используется как уникальный идентификатор.Если вы убедитесь, что объекты истории только из одной таблицы в одну папку, у вас нет проблем с определением различных ресурсов, имен файлов и т. Д.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...