Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

untymage's avatar

Can anyone explain Atomic Locks ?

I want to learn more about Atomic Locks: https://laravel.com/docs/8.x/cache#atomic-locks, the laravel doc is not clear for me, i will explain why,

Let say 100 requests hits my controller within one hour, but i want to only dispatch 1 job for all them So i did this:

public function update($product)
{
    $product->update(...);

    $lock = Cache::lock('productsIndex', 3600);

    if ($lock->get()) {
        UpdateProductsIndex::dispatch();
    }
}

What does $lock->get() ? it always return true in my side (in test env with sqlite database), Shouldn't it return false if the lock exists ? I set it to expire after 3600 second but it always return true.

0 likes
12 replies
tykus's avatar

$lock->get() means that you (the authenticated user) get (or acquire) the lock of the time specified (3600 seconds), or until you release the lock. You now have control over that action - and no-one else can acquire the lock.

It should return true unless someone else "has the lock".

2 likes
untymage's avatar

thanks, But i dont want to deal with auth users, I just want to dispatch one job whether it guest or auth (1 job in a hour, Isn't that what I'm looking for?

tykus's avatar

Yes, you're correct - I assumed incorrectly that it was bound to the auth user; it is not.

Are you using the array Cache driver in the test environment - I don't think this will persist between test runs???

untymage's avatar

The cache driver is database (SQLite) in test env, I test it on production and got the same thing, Another example let say i set the cronjob which hit the home root per minute , in the home root i would dispatch a job, But i want to dispatch a job 1 for a hour, So i just wondering if the Cache::lock can do it for us Or i can handle it by my self ?

tykus's avatar

Cache lock should work for this scenario; let me test here

1 like
parasume's avatar

@untymage, locks are used to limit concurrency. $lock->get() returns false if another process has already acquired a lock that has not been released / expired.

As to why your test sqlite database locks aren't working, that may be because you might be using a RefreshDatabase or similar testing trait that refreshes your database before another $lock->get() is fired. That may be what's preventing the lock to persist.

2 likes
stanliwise's avatar

Please make sure your CACHE_DRIVER is not set to array, use database, file etc

Please or to participate in this conversation.