Skip to content

PHP application-level database locking mechanisms to implement concurrency control patterns.

License

Notifications You must be signed in to change notification settings

cybercog/php-db-locker

Repository files navigation

PHP DB Locker

cog-php-db-locker

Releases License

Things to decide

  • Keep only PDO implementation, or make Doctrine/Eloquent drivers too?
  • Should wait mode be blocking or non-blocking by default?
  • Should callback for session lock be at the end of the params (after optional ones)?

Introduction

WARNING! This library is currently under development and may not be stable. Use in your services at your own risk.

PHP application-level database locking mechanisms to implement concurrency control patterns.

Supported drivers:

Installation

Pull in the package through Composer.

composer require cybercog/php-db-locker

Usage

Postgres

Transaction-level advisory lock

$dbConnection = new PDO($dsn, $username, $password);

$locker = new \Cog\DbLocker\Postgres\PostgresAdvisoryLocker();
$lockId = \Cog\DbLocker\Postgres\PostgresLockKey::create('user', '4');

$dbConnection->beginTransaction();
$lock = $locker->acquireSessionLevelLock(
    $dbConnection,
    $lockId,
    \Cog\DbLocker\Postgres\Enum\PostgresLockWaitModeEnum::NonBlocking,
    \Cog\DbLocker\Postgres\Enum\PostgresLockAccessModeEnum::Exclusive,
);
if ($lock->wasAcquired) {
    // Execute logic if lock was successful
} else {
    // Execute logic if lock acquisition has been failed
}
$dbConnection->commit();

Session-level advisory lock

Callback API

$dbConnection = new PDO($dsn, $username, $password);

$locker = new \Cog\DbLocker\Postgres\PostgresAdvisoryLocker();
$lockKey = \Cog\DbLocker\Postgres\PostgresLockKey::create('user', '4');

$payment = $locker->withinSessionLevelLock(
    dbConnection: $dbConnection,
    key: $lockKey,
    callback: function (
        \Cog\DbLocker\Postgres\LockHandle\SessionLevelLockHandle $lock, 
    ): Payment { // Define a type of $payment variable, so it will be resolved by analyzers
        if ($lock->wasAcquired) {
            // Execute logic if lock was successful
        } else {
            // Execute logic if lock acquisition has been failed
        }
    },
    waitMode: \Cog\DbLocker\Postgres\Enum\PostgresLockWaitModeEnum::NonBlocking,
    accessMode: \Cog\DbLocker\Postgres\Enum\PostgresLockAccessModeEnum::Exclusive,
);

Low-level API

$dbConnection = new PDO($dsn, $username, $password);

$locker = new \Cog\DbLocker\Postgres\PostgresAdvisoryLocker();
$lockKey = \Cog\DbLocker\Postgres\PostgresLockKey::create('user', '4');

try {
    $lock = $locker->acquireSessionLevelLock(
        dbConnection: $dbConnection,
        key: $lockKey,
        waitMode: \Cog\DbLocker\Postgres\Enum\PostgresLockWaitModeEnum::NonBlocking,
        accessMode: \Cog\DbLocker\Postgres\Enum\PostgresLockAccessModeEnum::Exclusive,
    );
    if ($lock->wasAcquired) {
        // Execute logic if lock was successful
    } else {
        // Execute logic if lock acquisition has been failed
    }
} finally {
    $lock->release();
}

Changelog

Detailed changes for each release are documented in the CHANGELOG.md.

License

🌟 Stargazers over time

Stargazers over time

About CyberCog

CyberCog is a Social Unity of enthusiasts. Research the best solutions in product & software development is our passion.

CyberCog

Releases

No releases published

Sponsor this project

Packages

No packages published