Как обрабатывать одновременный доступ в MySQL? - PullRequest
0 голосов
/ 08 июля 2019

Если на сайте покупок доступен только 1 продукт и 2 человека пытаются купить его одновременно, кто получит продукт? Как сервер установит приоритеты для пользователя. какой алгоритм?

1 Ответ

0 голосов
/ 09 июля 2019

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

Я предполагаю, что ваш сценарий:

  • Два пользователя, вошедшие в вашу систему, говорят, что они U1 и U2
  • Выберите товар
  • Доступен только один товар
  • Они оба нажали Добавить в корзину / Купить сейчас / Оформить заказ
  • Один пользователь будет обслуживаться, а другой пользователь будет уведомлен о том, что продукт больше не доступен

Предположим, T1 и T2 представляют наносекундное представление времени, когда они нажимали на кнопку оформления заказа. Вероятность того, что T1 и T2 равны друг другу, очень мала, но есть вероятность.

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

Следовательно, оба TH1 и TH2 попытаются завладеть вашим Продуктом.

Теперь вам нужно иметь / вводить два атрибута (представьте как столбцы MySQL) для ваших PRODUCT: VERSION и CHECKED_OUT.

И TH1, и TH2 начнут свои собственные транзакции одновременно, скажем, TR1 и TR2, предполагая, что в качестве ядра базы данных используется InnoDB.

Оба из TR1 и TR2 будут:

  • Считайте PRODUCT из таблицы базы данных вместе с VERSION и CHECKED_OUT: {id: 1, version: 0, checked_out: 0, ...} и передайте его на сервер.
  • На сервере оба параметра TR1 и TR2 увеличат значение VERSION, которое было прочитано ранее, и выполнят оператор Update, сообщающий, что UPDATE PRODUCT SET CHECKED_OUT = 1, VERSION = 1 WHERE ID = 1 AND VERSION = 0
  • DB заблокирует строку, выполнит UPDATE и вернет номер измененной строки последовательно, поскольку UPDATE должен быть выполнен в одном потоке. Обратите внимание, что этот поток является собственным потоком БД, а не TR1 и TR2.
  • Здесь, если я предполагаю, что TR1, т. Е. TH1 был обслужен раньше TR2, т. Е. TH2 потоком БД UPDATE, тогда бизнес-логика, стоящая за TR1, получит, что количество строк обновление равно 1, тогда как TR2 получит 0.
  • Что, в свою очередь, означает, что U1 получит возможность проверить продукт, тогда как U2 получит уведомление с хорошим извиняющимся сообщением.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...