Как избежать дублирования последовательных номеров, когда несколько записей вставляются в одно и то же время? - PullRequest
0 голосов
/ 31 марта 2020

Мое Laravel приложение является мультитенантным, с той же таблицей и той же базой данных, использующее внешний ключ team_id.

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

/**
 * Handle the "creating" event.
 *
 * @param  Product  $product
 * @return void
 */
public function creating(Product $product)
{
    $product->number = $product->team->products()->withTrashed()->max('number') + 1;
}

Но, как выясняется, когда в одно и то же время одновременно выполняется несколько запросов для одной и той же группы и типа ресурса, эти ресурсы получит тот же номер.

Какой лучший способ обойти это, не будучи слишком грязным?


Я думал о проверке и исправлении числа сразу после создания ресурса , но это немного грязно, и это приводит к 1 или 2 дополнительным запросам для каждого запроса. Но это может не сработать, если множественные запросы происходят в одно и то же время.

1 Ответ

0 голосов
/ 31 марта 2020

Быстрый способ исправить это - просто создать транзакцию при создании Продукта. Это будет SQL блокировать вашу таблицу до тех пор, пока блокировка не будет снята и для этого не будет правильных данных.

DB::transaction(function () {
    $product->save();
}, $attempts = 5);
...