Skip to content

Commit c745f54

Browse files
solflareLucas Graciano
and
Lucas Graciano
authored
Revert back to cache lock w/ firstOrCreate (#24)
While in a transaction upsert will lock the row until the transaction is finished. Using a cache lock avoids this but also introduces a possible duplicate exception in rare cases Co-authored-by: Lucas Graciano <[email protected]>
1 parent 167a87b commit c745f54

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

src/ProcessStamp.php

+12-12
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,21 @@ public static function firstOrCreateByProcess(array $process, ?string $hash = nu
5959
$parent = static::firstOrCreateByProcess(static::getProcessName($process['type'], $process['parent_name']));
6060
}
6161

62-
// Workaround races with `firstOrCreate` by leveraging a no-change upsert.
63-
// NOTE: Not using `insertOrIgnore` because of possible side-effects.
64-
static::upsert(
65-
[
66-
[
67-
'hash' => $hash,
62+
$stamp = static::where('hash', $hash)->first();
63+
64+
/*
65+
* If stamp does not exist in the database yet, go ahead and obtain a lock to create it.
66+
* This specifically doesn't lock as the first step to avoid all calls obtaining a lock from the cache if the item already exists in the DB.
67+
*/
68+
if (! $stamp) {
69+
Cache::lock('process-stamps-hash-create-' . $hash, 10)->get(function () use (&$stamp, $hash, $process, $parent) {
70+
$stamp = static::firstOrCreate(['hash' => $hash], [
6871
'name' => trim($process['name']),
6972
'type' => $process['type'],
7073
'parent_id' => optional($parent)->getKey(),
71-
],
72-
],
73-
['hash'], // Should be unique to hash.
74-
[] // Update nothing.
75-
);
76-
$stamp = static::where('hash', $hash)->first();
74+
]);
75+
});
76+
}
7777

7878
return $stamp;
7979
}

0 commit comments

Comments
 (0)