Параллельный доступ PHP + MySQL с проблемой генерации идентификатора

В механизме хранения InnoDB MySQL хранимая процедура используется для генерации значений первичного ключа в форме tbaaa000000,

Генерация ключей

Таким образом, формат первичного ключа:
Для фиксированной длины говорят l, первый two символы обозначают table_name, далее m бывают алфавиты и отдых (l-2-m) являются числовыми (только цифры).

Хранимая процедура была закодирована для ручного увеличения самого правого m+n кусок символов с использованием динамического SQL. Это делается путем нахождения наибольшего идентификатора (скажем, tbaaa999999 ) присутствует в таблице и увеличивает его (до tbaab000000). Под динамическим SQL я подразумеваю, что он использовался для динамического построения операторов SQL во время выполнения путем включения переменных в запрос.

Отправка формы

Предположим, мы пытаемся сгенерировать этот первичный ключ для таблицы. Table1, Также у нас есть другая таблица (скажем, Table2) который ссылается на первичный ключ Table1 (Table2 имеет внешний ключ на Table1).

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

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

Мои вопросы:

  1. Из-за параллелизма запросов, как я могу управлять генерацией и вставкой только уникальных идентификаторов в Table1?
  2. Как я могу получить сгенерированный первичный ключ Table1 обратно в скрипт PHP для вставки в Table2?

ТАК поощряет меня включать то, что я пробовал, поэтому я включил свои усилия. Однако я не хочу, чтобы объем ответов был ограничен, поэтому, пожалуйста, попробуйте придумать способ, прежде чем читать мое испытание.

Метод, о котором я подумал:

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

Я также исследовал try-catch метод в конце PHP-скрипта, который вызывает функцию для генерации и возврата идентификатора в PHP-скрипт. Это будет затем попытаться вставить в Table1 который потерпит неудачу, если такой же идентификатор уже существует (может быть, из-за одновременной обработки другого вставки для другого пользователя) и выбросит duplicate key exception и попробуйте снова, таким образом, давая уникальность. Тем не менее, я не уверен в этом методе, так как он может быть неэффективным и может вызвать проблемы с производительностью.

3

Решение

Для этого и нужны транзакции. Псевдокод для того, что вам нужно сделать:

  1. Начать транзакцию.
  2. Получите самый высокий идентификатор в таблице 1.
  3. Увеличьте это.
  4. Сохраните новую строку в таблице 1.
  5. Зафиксируйте транзакцию.

Если другой клиент попытается получить доступ к Таблице 1, пока это происходит, они будут заблокированы, пока транзакция не будет зафиксирована.

1

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

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector