Исправьте проблему параллелизма Laravel. Между условием if и вставкой eloquent - PullRequest
0 голосов
/ 08 апреля 2020

PHP версия: 7.2.4

Laravel версия: 5.8.34

MySQL версия: 5.6.41

MySQL тип сервера: MySQL

MySQL таблицы механизм хранения: InnoDB

Описание:

В этих кодах есть параллелизм:

...

$orderExist = Order::where('address', $address)
    ->where('order_status', 'open')
    ->where('type', 'bulk')
    ->where('way', 'site')
    ->whereDate('created_at', '>=', Carbon:today())
    ->whereNull('deleted_at')
    ->exists();

if (!$orderExist) {
    $order = Order::create([
        'admin_id' => auth()->user()->id,
        'address'  => $address,
        'status'   => 'open',
        'type'     => 'bulk',
        'way'      => 'site',
    ]);
} else {
    return 'duplicate_order';
}

OrderProduct::create([
    'order_id'   => $order->id,
    'product_id' => $product->id,
    'count'      => $request->count,
    'unit_id'    => $product->unit_id,
    'brand_id'   => $product->brand_id,
]);

...

Код сообщает нам : Если в таблице orders есть специальный порядок, вернитесь назад. Но если нет специального заказа, создайте новый заказ и после этого вставьте новый продукт для этого нового заказа.

Но иногда два запроса одновременно вставляют два повторяющихся заказа в таблицу orders.

Я нашел следующие способы:

  1. Laravel очередь: нет не возвращает новый вставленный идентификатор заказа, а также не может решить проблему параллелизма.
  2. Laravel транзакция: невозможно использовать условие if в этом. Кроме того, речь идет об откате нескольких запросов, если некоторые из них не были выполнены, и не касается проблемы разрешения параллелизма
  3. INSERT … ON DUPLICATE KEY UPDATE запрос: запрос вызывает выполнение обоих запросов. Поэтому это не правильно в отношении проблемы параллелизма.
  4. Таблица блокировок: механизм хранения InnoDB поддерживает только блокировку на уровне строк и не поддерживает блокировку на уровне таблиц, Основан на MyISAM-одновременных вставках и innodb-lock .
  5. ...

Пожалуйста, помогите мне решить эту проблему параллелизма.

1 Ответ

0 голосов
/ 16 апреля 2020

Может быть GET_LOCK() и RELEASE_LOCK().

...