Skip to content

fix(order): prevent duplicate order numbers under concurrent submit#399

Open
Ibochkarev wants to merge 1 commit into
betafrom
fix/issue-380-order-num-race
Open

fix(order): prevent duplicate order numbers under concurrent submit#399
Ibochkarev wants to merge 1 commit into
betafrom
fix/issue-380-order-num-race

Conversation

@Ibochkarev

Copy link
Copy Markdown
Member

Описание

Параллельный checkout/finalize мог выдать один и тот же msOrder.num: оба потока делали SELECT … LIKE prefix% ORDER BY id DESC, увеличивали счётчик и сохраняли без блокировки.

Теперь номер выделяется и сохраняется под MySQL GET_LOCK в OrderNumberGenerator::runWithNextNumber(), для черновиков num остаётся NULL, на колонку вешается UNIQUE (миграция чистит '' и разводит существующие дубликаты). Submit и finalize менеджера ходят через этот сервис.

Тип изменений

  • Исправление бага (non-breaking change)
  • Новая функциональность (non-breaking change)
  • Breaking change (изменение, ломающее обратную совместимость)
  • Рефакторинг (без изменения функциональности)
  • Документация
  • Другое (опишите):

Связанные Issues

Closes #380

Как это было протестировано?

  • Ручное тестирование
  • Автоматические тесты (PHPStan, ESLint)
  • Тестирование на разных версиях PHP/MODX

Конфигурация тестирования:

  • MiniShop3: ветка fix/issue-380-order-num-race
  • MODX: n/a (unit)
  • PHP: локальный CLI

Команды (exit 0):

  • php -l на всех затронутых PHP-файлах
  • php tests/OrderNumberGeneratorTest.php
  • php tests/PhinxMigrationTablePrefixTest.php (+ остальные tests/*.php)

Миграцию на живой БД в этом прогоне не применяли. Нагрузочный concurrent checkout не гоняли.

Скриншоты (если применимо)

До После
n/a n/a

Чеклист

  • Код соответствует стилю проекта
  • Добавлены/обновлены комментарии в сложных местах
  • Изменения не ломают существующую функциональность
  • Лексиконы добавлены на двух языках (ru/en)
  • PHPStan проходит без новых ошибок
  • ESLint проходит без ошибок (для JS/Vue изменений)
  • Обновлён CHANGELOG.md (для значимых изменений)

Дополнительные заметки

  • После деплоя нужна Phinx-миграция 20260716120000_add_unique_index_on_order_num.
  • Legacy Order::getNewOrderNum() / generate() помечены deprecated (WARN в лог): allocate без persist всё ещё подвержен гонке у плагинов; основные пути submit/finalize используют runWithNextNumber().
  • Атомарность смены статуса (соседний bug из issue) — вне scope этого PR.
  • Review: 1 fix-loop; blockers closed (silent counter fallback, schema sync, migration dedupe).

Allocate and persist msOrder.num under MySQL GET_LOCK, add UNIQUE index
with NULL drafts, and centralize generation in OrderNumberGenerator.
@Ibochkarev Ibochkarev added priority: medium Средний приоритет bug Something isn't working labels Jul 16, 2026
@Ibochkarev Ibochkarev requested a review from biz87 July 16, 2026 03:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority: medium Средний приоритет

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Генерация номера заказа без блокировки — дубликаты num

1 participant