可以首先在Laravel中原子地处理或创建吗?

时间:2016-08-23 19:30:46

标签: php laravel laravel-5

我有一个API,另一个应用程序挂钩上传一些用户数据。每个数据都属于一个用户,用户的电子邮件地址包含在每个API请求中。如果用户表中不存在该电子邮件,则会创建新用户,否则将在现有用户下添加新数据。

如果两个API请求背靠背,如果firstOrCreate将保证返回User对象,我需要这样做。在我当前的代码中,我正在查询数据库,如果用户不存在,我创建一个。但是我遇到了一个问题,即如果两个API调用背靠背,我会在数据库中插入两个(两个用户使用相同的电子邮件)。我已经在电子邮件列中添加了一个唯一约束,但我想确保如果我使用firstOrCreate,我将能够在此之后继续知道我已经拥有现有用户或者我已成功创建。< / p>

2 个答案:

答案 0 :(得分:2)

Laravel firstOrCreate没有原子卫士。但是,由于列上有UNIQUE约束,数据库将为您强制执行原子性。因此:

$params = [ 'email' => 'foo@example.com', /* ... */ ];
try {
    $user = User::firstOrCreate($params);
} catch (\Illuminate\Database\QueryException $ex) {
    $user = User::firstOrCreate($params);
}

如果第一次失败,那么你就会争用。所以它重试了这次尝试。据推测,第二次尝试将返回第一个记录匹配。但是,请注意Illuminate\Database\QueryException可能由于多种原因而发生,唯一的密钥违规就是其中之一。因此,可以进行第二次尝试,但仍然没有实际返回用户。

答案 1 :(得分:0)

将唯一键添加到电子邮件列。 $table->string('email')->unique();