【问题标题】:How to avoid duplicate sequential numbers when multiple records are inserted at the exact same time?当多条记录同时插入时,如何避免重复的序号?
【发布时间】:2020-07-11 09:51:20
【问题描述】:

我的 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 个额外的查询。但是,如果多个请求同时发生,这可能仍然行不通。

【问题讨论】:

标签: mysql laravel increment multi-tenant


【解决方案1】:

修复它的快速方法是在创建产品时简单地创建一个transaction。这将 SQL 锁定您的表,直到锁定被释放并因此获得正确的数据。

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

【讨论】:

  • 这不会同时对其他请求造成错误/阻塞?
  • 是的,但交易应该几乎是瞬间完成的。
  • 嗯,你能详细说明一下吗?因为我仍然希望多个请求在每次同时发生时都能成功。
  • 保存操作相当快,几乎是瞬间完成,将它与同样快速的 max 调用结合起来,它不会长时间锁定数据库,并且可能不会导致锁定超时,除非你被请求轰炸。试试看,看看你的错误报告是否起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-15
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 2011-09-29
  • 2015-04-27
相关资源
最近更新 更多