Skip to content

Instantly share code, notes, and snippets.

@tjimenez
Forked from troatie/CreatesWithLock.php
Created October 27, 2022 01:06
Show Gist options
  • Select an option

  • Save tjimenez/4509e3cee947d5b2cfdc2a266e55b8e7 to your computer and use it in GitHub Desktop.

Select an option

Save tjimenez/4509e3cee947d5b2cfdc2a266e55b8e7 to your computer and use it in GitHub Desktop.

Revisions

  1. @troatie troatie renamed this gist Jun 20, 2018. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions CreatesWithLock.md → CreatesWithLock.php
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@
    ```php
    trait CreatesWithLock
    {
    public static function updateOrCreate(array $attributes, array $values = [])
    @@ -34,5 +33,4 @@ private static function advisoryLock(callable $callback)
    \DB::statement("SELECT RELEASE_LOCK('" . $lockName . "')");
    return $output;
    }
    }
    ```
    }
  2. @troatie troatie renamed this gist Jun 20, 2018. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion CreatesWithLock.php → CreatesWithLock.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    ```php
    trait CreatesWithLock
    {
    public static function updateOrCreate(array $attributes, array $values = [])
    @@ -33,4 +34,5 @@ private static function advisoryLock(callable $callback)
    \DB::statement("SELECT RELEASE_LOCK('" . $lockName . "')");
    return $output;
    }
    }
    }
    ```
  3. @troatie troatie created this gist Jun 20, 2018.
    36 changes: 36 additions & 0 deletions CreatesWithLock.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    trait CreatesWithLock
    {
    public static function updateOrCreate(array $attributes, array $values = [])
    {
    return static::advisoryLock(function () use ($attributes, $values) {
    // emulate the code found in Illuminate\Database\Eloquent\Builder
    return (new static)->newQuery()->updateOrCreate($attributes, $values);
    });
    }

    public static function firstOrCreate(array $attributes, array $values = [])
    {
    return static::advisoryLock(function () use ($attributes, $values) {
    return (new static)->newQuery()->firstOrCreate($attributes, $values);
    });
    }

    /**
    * In my project, this advisoryLock method actually lives as a function on the global namespace (similar to Laravel Helpers).
    * In that case the $lockName, and default lock duration are pased in as arguments.
    */
    private static function advisoryLock(callable $callback)
    {
    // Lock name based on Model.
    $lockName = substr(static::class . ' *OrCreate lock', -64);

    // Lock for at most 10 seconds. This is the MySQL >5.7.5 implementation.
    // Older MySQL versions have some weird behavior with GET_LOCK().
    // Other databases have a different implementation.
    \DB::statement("SELECT GET_LOCK('" . $lockName . "', 10)");

    $output = $callback();
    \DB::statement("SELECT RELEASE_LOCK('" . $lockName . "')");
    return $output;
    }
    }