PHPackages                             brick/lock - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. brick/lock

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

brick/lock
==========

Advisory locks library

0.1.0(9mo ago)6793↓50%[1 issues](https://github.com/brick/lock/issues)MITPHPPHP ^8.2CI passing

Since Aug 16Pushed 8mo ago1 watchersCompare

[ Source](https://github.com/brick/lock)[ Packagist](https://packagist.org/packages/brick/lock)[ GitHub Sponsors](https://github.com/BenMorel)[ RSS](/packages/brick-lock/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (7)Versions (3)Used By (0)

Brick\\Lock
===========

[](#bricklock)

[![](https://raw.githubusercontent.com/brick/brick/master/logo.png)](https://raw.githubusercontent.com/brick/brick/master/logo.png)

Advisory locking for PHP applications.

[![Build Status](https://github.com/brick/lock/workflows/CI/badge.svg)](https://github.com/brick/lock/actions)[![Latest Stable Version](https://camo.githubusercontent.com/c9cb97978f743eb32c89995c334738f6635e988f86fc2a8f357e2451a5287a4e/68747470733a2f2f706f7365722e707567782e6f72672f627269636b2f6c6f636b2f762f737461626c65)](https://packagist.org/packages/brick/lock)[![Total Downloads](https://camo.githubusercontent.com/edfca7b386a59aef8f47fb3c50b86d7784b92ba914b9d6f65564b52924451c84/68747470733a2f2f706f7365722e707567782e6f72672f627269636b2f6c6f636b2f646f776e6c6f616473)](https://packagist.org/packages/brick/lock)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](http://opensource.org/licenses/MIT)

Overview
--------

[](#overview)

This library provides a simple interface to work with advisory (named) locks for inter-process synchronization.

It works by using a database (MySQL, MariaDB or PostgreSQL) as a backend for locks. This allows the locks to work across multiple processes, and even across different web servers. It uses the native advisory locking functionality of each database (`GET_LOCK()` on MySQL / MariaDB, `pg_advisory_lock()` on PostgreSQL).

Locks are tied to the database connection they were created with, and are automatically released when the connection is closed, which prevents locks from remaining unreleased after a crash or a bug.

Locks are not affected by transactions, so it is safe to use your existing database connection.

Installation
------------

[](#installation)

This library is installable via [Composer](https://getcomposer.org/):

```
composer require brick/lock
```

Requirements
------------

[](#requirements)

This library requires PHP 8.2 or later.

Project status &amp; release process
------------------------------------

[](#project-status--release-process)

This library is under development and its API may evolve, but it is well-tested and considered ready for production use.

The current releases are numbered `0.x.y`. When a non-breaking change is introduced (adding new methods, optimizing existing code, etc.), `y` is incremented.

**When a breaking change is introduced, a new `0.x` version cycle is always started.**

It is therefore safe to lock your project to a given release cycle, such as `0.1.*`.

If you need to upgrade to a newer release cycle, check the [release history](https://github.com/brick/lock/releases) for a list of changes introduced by each further `0.x.0` version.

Usage
-----

[](#usage)

You first need to instantiate a lock driver. For example, to use MySQL over a PDO connection:

```
use Brick\Lock\Database\Connection\PdoConnection;
use Brick\Lock\Driver\MysqlLockDriver;

$pdo = new PDO('mysql:host=localhost', 'user', 'password');
$connection = new PdoConnection($pdo);
$driver = new MysqlLockDriver($connection);
```

Tip

Available connections: `PdoConnection`, `DoctrineConnection`
Available drivers: `MysqlLockDriver`, `MariadbLockDriver`, `PostgresLockDriver`

You can then instantiate the lock factory, which is the entry point to create named locks:

```
use Brick\Lock\LockFactory;

$lockFactory = new LockFactory($driver);
```

You can now create a lock object using a unique name that identifies the resource you want to lock:

```
$lock = $lockFactory->createLock('my_lock_name');
```

And use it to acquire a lock:

```
$lock->acquire();
// ... do some work while the lock is held ...
$lock->release();
```

The `LockInterface` object
--------------------------

[](#the-lockinterface-object)

The object returned by `createLock()` implements `LockInterface`, which provides the following methods:

- **`acquire(): void`**

    Acquires the lock, blocking until it is available.

    ```
    $lock->acquire();
    ```
- **`tryAcquire(): bool`**

    Tries to acquire the lock, non-blocking.

    If the lock can be acquired immediately, this method returns `true` and the lock is held. If the lock is currently held by another process, this method returns `false` and does not hold the lock.

    ```
    if ($lock->tryAcquire()) {
        // the lock is acquired
    } else {
        // the lock is currently held by another process
    }
    ```
- **`tryAcquireWithTimeout(int $seconds): bool`**

    Tries to acquire the lock, with a maximum wait time.

    If the lock can be acquired before the timeout expires, this method returns `true` and the lock is held. If the lock cannot be acquired before the timeout expires, this method returns `false` and does not hold the lock.

    ```
    if ($lock->tryAcquireWithTimeout(10)) {
        // the lock is acquired
    } else {
        // the lock could not be acquired after 10s
    }
    ```
- **`release(): void`**

    Releases the lock.

    ```
    $lock->release();
    ```

    Attempting to release a lock that is not held throws a `LockReleaseException`.
- **`wait(): void`**

    Waits until the lock is available, without acquiring it.

    This can be used after an unsuccessful `tryAcquire()` attempt, to wait for the result of the same operation performed by another process.

    ```
    $lock->wait();
    ```
- **`tryWaitWithTimeout(int $seconds): bool`**

    Waits until the lock is available, or the timeout expires.

    This method does not acquire the lock.

    ```
    if ($lock->tryWaitWithTimeout(10)) {
        // the lock was available before the end of the timeout
    } else {
        // the lock was still not available after 10s
    }
    ```
- **`synchronize(Closure(): T $task): T`**

    Executes the given task while holding the lock.

    Once the lock is acquired, the closure is executed, and its return value is returned as is. If the closure throws an exception, the lock is released and the exception bubbles up. This method is blocking and will wait for the lock to become available.

    ```
    $result = $lock->synchronize(function() {
        // ...do some work that requires an exclusive lock...

        return 'some value';
    });

    // $result === 'some value'
    ```
- **`trySynchronize(Closure(): T $task): SynchronizeSuccess|null`**

    Executes the given task while holding the lock, non-blocking.

    If the lock is available immediately, it is acquired, the closure is executed, and its return value is returned wrapped in a `SynchronizeSuccess` object. If the lock is currently held by another process, this method returns `null`. If the closure throws an exception, the lock is released and the exception bubbles up.

    ```
    $result = $lock->trySynchronize(function() {
        // ...do some work that requires an exclusive lock...

        return 'some value';
    });

    if ($result !== null) {
        // the lock was acquired and the closure was executed
        // $result->returnValue === 'some value'
    } else {
        // the lock was not available
    }
    ```
- **`trySynchronizeWithTimeout(int $seconds, Closure(): T $task): SynchronizeSuccess|null`**

    Executes the given task while holding the lock, with a maximum wait time.

    If the lock is successfully acquired before the timeout expires, the closure is executed, and its return value is returned wrapped in a `SynchronizeSuccess` object. If the lock cannot be acquired before the timeout expires, this method returns `null`. If the closure throws an exception, the lock is released and the exception bubbles up.

    ```
    $result = $lock->trySynchronizeWithTimeout(10, function() {
        // ...do some work that requires an exclusive lock...

        return 'some value';
    });

    if ($result !== null) {
        // the lock was acquired and the closure was executed
        // $result->returnValue === 'some value'
    } else {
        // the lock was still not available after 10s
    }
    ```

Acquiring multiple locks
------------------------

[](#acquiring-multiple-locks)

If you need to acquire multiple locks at once, use:

```
$lock = $lockFactory->createMultiLock(['my_lock_name_1', 'my_lock_name_2']);
```

The object returned by `createMultiLock()` implements the same `LockInterface` as the single lock, so you can use it in exactly the same way.

The locks are acquired atomically, i.e. either all locks are acquired, or none of them are.

Reentrancy
----------

[](#reentrancy)

Locks in this library are **reentrant** (also known as recursive locks), meaning the same process can acquire a lock multiple times without causing a deadlock. This is particularly useful for recursive methods that call themselves, or when methods call other methods that also need the same lock.

**How It Works**

- Each time a process acquires a reentrant lock, an internal counter is incremented
- The lock is only fully released when the counter returns to zero
- Other processes must wait until the lock is completely released before they can acquire it

```
$lock->acquire(); // Counter: 1 - blocks until the lock is available
$lock->acquire(); // Counter: 2 - returns immediately
$lock->acquire(); // Counter: 3 - returns immediately

$lock->release(); // Counter: 2 - lock is still held
$lock->release(); // Counter: 1 - lock is still held
$lock->release(); // Counter: 0 - lock is now fully released
```

Exceptions
----------

[](#exceptions)

Depending on the operation called, the following exceptions may be thrown:

- `LockAcquireException`
- `LockReleaseException`
- `LockWaitException`

All of these exceptions extend `LockException`, which can be used to catch all lock-related exceptions.

These exceptions **are only thrown when an error occurs**, not in normal conditions like failure to acquire a lock due to another process holding it. For example, `tryAcquire()` will return `false` if the lock cannot be acquired immediately, and only throw a `LockAcquireException` if an error occurs and the status of the lock cannot be determined.

Tip

Check the source code of `LockInterface` for detailed information about the exceptions thrown by each method.

Use in a Symfony project
------------------------

[](#use-in-a-symfony-project)

In a Symfony project, add the following config, typically in `config/services.yaml`:

```
services:
    Brick\Lock\LockFactoryInterface:
        class: Brick\Lock\LockFactory

    # Choose the driver that corresponds to your database:
    Brick\Lock\LockDriverInterface:
        class: Brick\Lock\Driver\MysqlLockDriver
        # class: Brick\Lock\Driver\MariadbLockDriver
        # class: Brick\Lock\Driver\PostgresLockDriver

    # Choose the connection you want to use:
    Brick\Lock\Database\ConnectionInterface:
        class: Brick\Lock\Database\Connection\DoctrineConnection
        # class: Brick\Lock\Database\Connection\PdoConnection
```

Tip

In a typical Symfony project using the Doctrine ORM, you'll probably want to use `DoctrineConnection`.

You can now type-hint the `Brick\Lock\LockFactoryInterface` service in your code and use it to create locks.

Alternatives
------------

[](#alternatives)

You may also want to consider the following projects:

- **[symfony/lock](https://symfony.com/doc/current/components/lock.html)**
- **[php-lock/lock](https://github.com/php-lock/lock)**

Please see the [alternatives](docs/alternatives.md) documentation for a detailed comparison of these libraries with brick/lock.

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance56

Moderate activity, may be stable

Popularity24

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

 Bus Factor1

Top contributor holds 97.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

275d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/57189121968030f0770811b461cc92f9c19c08f5c4767292f2ede48b7277cfad?d=identicon)[BenMorel](/maintainers/BenMorel)

---

Top Contributors

[![BenMorel](https://avatars.githubusercontent.com/u/1952838?v=4)](https://github.com/BenMorel "BenMorel (46 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (1 commits)")

---

Tags

brickmutexlock

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/brick-lock/health.svg)

```
[![Health](https://phpackages.com/badges/brick-lock/health.svg)](https://phpackages.com/packages/brick-lock)
```

###  Alternatives

[brick/math

Arbitrary-precision arithmetic library

2.1k504.0M277](/packages/brick-math)[brick/money

Money and currency library

1.9k37.9M102](/packages/brick-money)[symfony/lock

Creates and manages locks, a mechanism to provide exclusive access to a shared resource

514127.6M459](/packages/symfony-lock)[brick/date-time

Date and time library

3623.3M61](/packages/brick-date-time)[brick/geo

GIS geometry library

245862.1k15](/packages/brick-geo)[brick/schema

Schema.org library for PHP

5163.7k1](/packages/brick-schema)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
